^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Host side test driver to test endpoint functionality
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2017 Texas Instruments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Author: Kishon Vijay Abraham I <kishon@ti.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/crc32.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/miscdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/random.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/pci_ids.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/pci_regs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <uapi/linux/pcitest.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define DRV_MODULE_NAME "pci-endpoint-test"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define IRQ_TYPE_UNDEFINED -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define IRQ_TYPE_LEGACY 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define IRQ_TYPE_MSI 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define IRQ_TYPE_MSIX 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define PCI_ENDPOINT_TEST_MAGIC 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define PCI_ENDPOINT_TEST_COMMAND 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define COMMAND_RAISE_LEGACY_IRQ BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define COMMAND_RAISE_MSI_IRQ BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define COMMAND_RAISE_MSIX_IRQ BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define COMMAND_READ BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define COMMAND_WRITE BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define COMMAND_COPY BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define PCI_ENDPOINT_TEST_STATUS 0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define STATUS_READ_SUCCESS BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define STATUS_READ_FAIL BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define STATUS_WRITE_SUCCESS BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define STATUS_WRITE_FAIL BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define STATUS_COPY_SUCCESS BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define STATUS_COPY_FAIL BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define STATUS_IRQ_RAISED BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define STATUS_SRC_ADDR_INVALID BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define STATUS_DST_ADDR_INVALID BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define PCI_ENDPOINT_TEST_LOWER_SRC_ADDR 0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define PCI_ENDPOINT_TEST_UPPER_SRC_ADDR 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define PCI_ENDPOINT_TEST_LOWER_DST_ADDR 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define PCI_ENDPOINT_TEST_UPPER_DST_ADDR 0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define PCI_ENDPOINT_TEST_SIZE 0x1c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define PCI_ENDPOINT_TEST_CHECKSUM 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define PCI_ENDPOINT_TEST_IRQ_TYPE 0x24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define PCI_ENDPOINT_TEST_IRQ_NUMBER 0x28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define PCI_ENDPOINT_TEST_FLAGS 0x2c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define FLAG_USE_DMA BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define PCI_DEVICE_ID_TI_J721E 0xb00d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define PCI_DEVICE_ID_TI_AM654 0xb00c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define PCI_DEVICE_ID_LS1088A 0x80c0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define is_am654_pci_dev(pdev) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) ((pdev)->device == PCI_DEVICE_ID_TI_AM654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define PCI_DEVICE_ID_RENESAS_R8A774A1 0x0028
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define PCI_DEVICE_ID_RENESAS_R8A774B1 0x002b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define PCI_DEVICE_ID_RENESAS_R8A774C0 0x002d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define PCI_DEVICE_ID_RENESAS_R8A774E1 0x0025
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static DEFINE_IDA(pci_endpoint_test_ida);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define to_endpoint_test(priv) container_of((priv), struct pci_endpoint_test, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) miscdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) static bool no_msi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) module_param(no_msi, bool, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) MODULE_PARM_DESC(no_msi, "Disable MSI interrupt in pci_endpoint_test");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) static int irq_type = IRQ_TYPE_MSI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) module_param(irq_type, int, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) MODULE_PARM_DESC(irq_type, "IRQ mode selection in pci_endpoint_test (0 - Legacy, 1 - MSI, 2 - MSI-X)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) enum pci_barno {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) BAR_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) BAR_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) BAR_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) BAR_3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) BAR_4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) BAR_5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct pci_endpoint_test {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) struct pci_dev *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) void __iomem *bar[PCI_STD_NUM_BARS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct completion irq_raised;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) int last_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) int num_irqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) int irq_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /* mutex to protect the ioctls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct mutex mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct miscdevice miscdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) enum pci_barno test_reg_bar;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) size_t alignment;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct pci_endpoint_test_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) enum pci_barno test_reg_bar;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) size_t alignment;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) int irq_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static inline u32 pci_endpoint_test_readl(struct pci_endpoint_test *test,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) u32 offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return readl(test->base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static inline void pci_endpoint_test_writel(struct pci_endpoint_test *test,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) u32 offset, u32 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) writel(value, test->base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) static inline u32 pci_endpoint_test_bar_readl(struct pci_endpoint_test *test,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) int bar, int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return readl(test->bar[bar] + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) static inline void pci_endpoint_test_bar_writel(struct pci_endpoint_test *test,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) int bar, u32 offset, u32 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) writel(value, test->bar[bar] + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static irqreturn_t pci_endpoint_test_irqhandler(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) struct pci_endpoint_test *test = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) reg = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (reg & STATUS_IRQ_RAISED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) test->last_irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) complete(&test->irq_raised);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) reg &= ~STATUS_IRQ_RAISED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) static void pci_endpoint_test_free_irq_vectors(struct pci_endpoint_test *test)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) struct pci_dev *pdev = test->pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) pci_free_irq_vectors(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) test->irq_type = IRQ_TYPE_UNDEFINED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) static bool pci_endpoint_test_alloc_irq_vectors(struct pci_endpoint_test *test,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) int irq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) struct pci_dev *pdev = test->pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) bool res = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) case IRQ_TYPE_LEGACY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) irq = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_LEGACY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (irq < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) dev_err(dev, "Failed to get Legacy interrupt\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) case IRQ_TYPE_MSI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) irq = pci_alloc_irq_vectors(pdev, 1, 32, PCI_IRQ_MSI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (irq < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) dev_err(dev, "Failed to get MSI interrupts\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) case IRQ_TYPE_MSIX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) irq = pci_alloc_irq_vectors(pdev, 1, 2048, PCI_IRQ_MSIX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) if (irq < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) dev_err(dev, "Failed to get MSI-X interrupts\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) dev_err(dev, "Invalid IRQ type selected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (irq < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) irq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) res = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) test->irq_type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) test->num_irqs = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) static void pci_endpoint_test_release_irq(struct pci_endpoint_test *test)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) struct pci_dev *pdev = test->pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) for (i = 0; i < test->num_irqs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) devm_free_irq(dev, pci_irq_vector(pdev, i), test);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) test->num_irqs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) static bool pci_endpoint_test_request_irq(struct pci_endpoint_test *test)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) struct pci_dev *pdev = test->pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) for (i = 0; i < test->num_irqs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) err = devm_request_irq(dev, pci_irq_vector(pdev, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) pci_endpoint_test_irqhandler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) IRQF_SHARED, test->name, test);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) switch (irq_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) case IRQ_TYPE_LEGACY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) dev_err(dev, "Failed to request IRQ %d for Legacy\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) pci_irq_vector(pdev, i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) case IRQ_TYPE_MSI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) dev_err(dev, "Failed to request IRQ %d for MSI %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) pci_irq_vector(pdev, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) i + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) case IRQ_TYPE_MSIX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) dev_err(dev, "Failed to request IRQ %d for MSI-X %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) pci_irq_vector(pdev, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) i + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) static bool pci_endpoint_test_bar(struct pci_endpoint_test *test,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) enum pci_barno barno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) struct pci_dev *pdev = test->pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (!test->bar[barno])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) size = pci_resource_len(pdev, barno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) if (barno == test->test_reg_bar)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) size = 0x4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) for (j = 0; j < size; j += 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) pci_endpoint_test_bar_writel(test, barno, j, 0xA0A0A0A0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) for (j = 0; j < size; j += 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) val = pci_endpoint_test_bar_readl(test, barno, j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (val != 0xA0A0A0A0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) static bool pci_endpoint_test_legacy_irq(struct pci_endpoint_test *test)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) IRQ_TYPE_LEGACY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) COMMAND_RAISE_LEGACY_IRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) val = wait_for_completion_timeout(&test->irq_raised,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) msecs_to_jiffies(1000));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if (!val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) static bool pci_endpoint_test_msi_irq(struct pci_endpoint_test *test,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) u16 msi_num, bool msix)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) struct pci_dev *pdev = test->pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) msix == false ? IRQ_TYPE_MSI :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) IRQ_TYPE_MSIX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, msi_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) msix == false ? COMMAND_RAISE_MSI_IRQ :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) COMMAND_RAISE_MSIX_IRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) val = wait_for_completion_timeout(&test->irq_raised,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) msecs_to_jiffies(1000));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) if (!val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) if (pci_irq_vector(pdev, msi_num - 1) == test->last_irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) static bool pci_endpoint_test_copy(struct pci_endpoint_test *test,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) struct pci_endpoint_test_xfer_param param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) bool ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) void *src_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) void *dst_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) u32 flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) bool use_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) size_t size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) dma_addr_t src_phys_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) dma_addr_t dst_phys_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) struct pci_dev *pdev = test->pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) void *orig_src_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) dma_addr_t orig_src_phys_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) void *orig_dst_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) dma_addr_t orig_dst_phys_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) size_t offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) size_t alignment = test->alignment;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) int irq_type = test->irq_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) u32 src_crc32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) u32 dst_crc32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) err = copy_from_user(¶m, (void __user *)arg, sizeof(param));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) dev_err(dev, "Failed to get transfer param\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) size = param.size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) if (size > SIZE_MAX - alignment)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) use_dma = !!(param.flags & PCITEST_FLAGS_USE_DMA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (use_dma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) flags |= FLAG_USE_DMA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) if (irq_type < IRQ_TYPE_LEGACY || irq_type > IRQ_TYPE_MSIX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) dev_err(dev, "Invalid IRQ type option\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) orig_src_addr = kzalloc(size + alignment, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if (!orig_src_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) dev_err(dev, "Failed to allocate source buffer\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) get_random_bytes(orig_src_addr, size + alignment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) orig_src_phys_addr = dma_map_single(dev, orig_src_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) size + alignment, DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (dma_mapping_error(dev, orig_src_phys_addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) dev_err(dev, "failed to map source buffer address\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) goto err_src_phys_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) if (alignment && !IS_ALIGNED(orig_src_phys_addr, alignment)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) src_phys_addr = PTR_ALIGN(orig_src_phys_addr, alignment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) offset = src_phys_addr - orig_src_phys_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) src_addr = orig_src_addr + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) src_phys_addr = orig_src_phys_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) src_addr = orig_src_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_LOWER_SRC_ADDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) lower_32_bits(src_phys_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_UPPER_SRC_ADDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) upper_32_bits(src_phys_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) src_crc32 = crc32_le(~0, src_addr, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) orig_dst_addr = kzalloc(size + alignment, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) if (!orig_dst_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) dev_err(dev, "Failed to allocate destination address\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) goto err_dst_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) orig_dst_phys_addr = dma_map_single(dev, orig_dst_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) size + alignment, DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) if (dma_mapping_error(dev, orig_dst_phys_addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) dev_err(dev, "failed to map destination buffer address\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) goto err_dst_phys_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (alignment && !IS_ALIGNED(orig_dst_phys_addr, alignment)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) dst_phys_addr = PTR_ALIGN(orig_dst_phys_addr, alignment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) offset = dst_phys_addr - orig_dst_phys_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) dst_addr = orig_dst_addr + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) dst_phys_addr = orig_dst_phys_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) dst_addr = orig_dst_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_LOWER_DST_ADDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) lower_32_bits(dst_phys_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_UPPER_DST_ADDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) upper_32_bits(dst_phys_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_FLAGS, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) COMMAND_COPY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) wait_for_completion(&test->irq_raised);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) dma_unmap_single(dev, orig_dst_phys_addr, size + alignment,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) dst_crc32 = crc32_le(~0, dst_addr, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) if (dst_crc32 == src_crc32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) err_dst_phys_addr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) kfree(orig_dst_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) err_dst_addr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) dma_unmap_single(dev, orig_src_phys_addr, size + alignment,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) err_src_phys_addr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) kfree(orig_src_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) static bool pci_endpoint_test_write(struct pci_endpoint_test *test,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) struct pci_endpoint_test_xfer_param param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) bool ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) u32 flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) bool use_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) void *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) dma_addr_t phys_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) struct pci_dev *pdev = test->pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) void *orig_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) dma_addr_t orig_phys_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) size_t offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) size_t alignment = test->alignment;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) int irq_type = test->irq_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) size_t size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) u32 crc32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) err = copy_from_user(¶m, (void __user *)arg, sizeof(param));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) if (err != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) dev_err(dev, "Failed to get transfer param\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) size = param.size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) if (size > SIZE_MAX - alignment)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) use_dma = !!(param.flags & PCITEST_FLAGS_USE_DMA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if (use_dma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) flags |= FLAG_USE_DMA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) if (irq_type < IRQ_TYPE_LEGACY || irq_type > IRQ_TYPE_MSIX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) dev_err(dev, "Invalid IRQ type option\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) orig_addr = kzalloc(size + alignment, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (!orig_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) dev_err(dev, "Failed to allocate address\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) get_random_bytes(orig_addr, size + alignment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) orig_phys_addr = dma_map_single(dev, orig_addr, size + alignment,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (dma_mapping_error(dev, orig_phys_addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) dev_err(dev, "failed to map source buffer address\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) goto err_phys_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) if (alignment && !IS_ALIGNED(orig_phys_addr, alignment)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) phys_addr = PTR_ALIGN(orig_phys_addr, alignment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) offset = phys_addr - orig_phys_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) addr = orig_addr + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) phys_addr = orig_phys_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) addr = orig_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) crc32 = crc32_le(~0, addr, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_CHECKSUM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) crc32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_LOWER_SRC_ADDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) lower_32_bits(phys_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_UPPER_SRC_ADDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) upper_32_bits(phys_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_FLAGS, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) COMMAND_READ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) wait_for_completion(&test->irq_raised);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) reg = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) if (reg & STATUS_READ_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) dma_unmap_single(dev, orig_phys_addr, size + alignment,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) err_phys_addr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) kfree(orig_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) static bool pci_endpoint_test_read(struct pci_endpoint_test *test,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) struct pci_endpoint_test_xfer_param param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) bool ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) u32 flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) bool use_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) size_t size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) void *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) dma_addr_t phys_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) struct pci_dev *pdev = test->pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) void *orig_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) dma_addr_t orig_phys_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) size_t offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) size_t alignment = test->alignment;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) int irq_type = test->irq_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) u32 crc32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) err = copy_from_user(¶m, (void __user *)arg, sizeof(param));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) dev_err(dev, "Failed to get transfer param\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) size = param.size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) if (size > SIZE_MAX - alignment)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) use_dma = !!(param.flags & PCITEST_FLAGS_USE_DMA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) if (use_dma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) flags |= FLAG_USE_DMA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) if (irq_type < IRQ_TYPE_LEGACY || irq_type > IRQ_TYPE_MSIX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) dev_err(dev, "Invalid IRQ type option\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) orig_addr = kzalloc(size + alignment, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) if (!orig_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) dev_err(dev, "Failed to allocate destination address\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) orig_phys_addr = dma_map_single(dev, orig_addr, size + alignment,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) if (dma_mapping_error(dev, orig_phys_addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) dev_err(dev, "failed to map source buffer address\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) goto err_phys_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) if (alignment && !IS_ALIGNED(orig_phys_addr, alignment)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) phys_addr = PTR_ALIGN(orig_phys_addr, alignment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) offset = phys_addr - orig_phys_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) addr = orig_addr + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) phys_addr = orig_phys_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) addr = orig_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_LOWER_DST_ADDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) lower_32_bits(phys_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_UPPER_DST_ADDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) upper_32_bits(phys_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_FLAGS, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) COMMAND_WRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) wait_for_completion(&test->irq_raised);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) dma_unmap_single(dev, orig_phys_addr, size + alignment,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) crc32 = crc32_le(~0, addr, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) if (crc32 == pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_CHECKSUM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) err_phys_addr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) kfree(orig_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) static bool pci_endpoint_test_clear_irq(struct pci_endpoint_test *test)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) pci_endpoint_test_release_irq(test);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) pci_endpoint_test_free_irq_vectors(test);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) static bool pci_endpoint_test_set_irq(struct pci_endpoint_test *test,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) int req_irq_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) struct pci_dev *pdev = test->pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) if (req_irq_type < IRQ_TYPE_LEGACY || req_irq_type > IRQ_TYPE_MSIX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) dev_err(dev, "Invalid IRQ type option\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) if (test->irq_type == req_irq_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) pci_endpoint_test_release_irq(test);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) pci_endpoint_test_free_irq_vectors(test);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) if (!pci_endpoint_test_alloc_irq_vectors(test, req_irq_type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) if (!pci_endpoint_test_request_irq(test))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) pci_endpoint_test_free_irq_vectors(test);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) static long pci_endpoint_test_ioctl(struct file *file, unsigned int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) int ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) enum pci_barno bar;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) struct pci_endpoint_test *test = to_endpoint_test(file->private_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) struct pci_dev *pdev = test->pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) mutex_lock(&test->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) case PCITEST_BAR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) bar = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) if (bar < 0 || bar > 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) goto ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) if (is_am654_pci_dev(pdev) && bar == BAR_0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) goto ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) ret = pci_endpoint_test_bar(test, bar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) case PCITEST_LEGACY_IRQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) ret = pci_endpoint_test_legacy_irq(test);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) case PCITEST_MSI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) case PCITEST_MSIX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) ret = pci_endpoint_test_msi_irq(test, arg, cmd == PCITEST_MSIX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) case PCITEST_WRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) ret = pci_endpoint_test_write(test, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) case PCITEST_READ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) ret = pci_endpoint_test_read(test, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) case PCITEST_COPY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) ret = pci_endpoint_test_copy(test, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) case PCITEST_SET_IRQTYPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) ret = pci_endpoint_test_set_irq(test, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) case PCITEST_GET_IRQTYPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) ret = irq_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) case PCITEST_CLEAR_IRQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) ret = pci_endpoint_test_clear_irq(test);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) ret:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) mutex_unlock(&test->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) static const struct file_operations pci_endpoint_test_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) .unlocked_ioctl = pci_endpoint_test_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) static int pci_endpoint_test_probe(struct pci_dev *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) const struct pci_device_id *ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) char name[24];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) enum pci_barno bar;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) struct pci_endpoint_test *test;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) struct pci_endpoint_test_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) enum pci_barno test_reg_bar = BAR_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) struct miscdevice *misc_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) if (pci_is_bridge(pdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) test = devm_kzalloc(dev, sizeof(*test), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) if (!test)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) test->test_reg_bar = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) test->alignment = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) test->pdev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) test->irq_type = IRQ_TYPE_UNDEFINED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) if (no_msi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) irq_type = IRQ_TYPE_LEGACY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) data = (struct pci_endpoint_test_data *)ent->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) if (data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) test_reg_bar = data->test_reg_bar;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) test->test_reg_bar = test_reg_bar;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) test->alignment = data->alignment;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) irq_type = data->irq_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) init_completion(&test->irq_raised);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) mutex_init(&test->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) if ((dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(48)) != 0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) dev_err(dev, "Cannot set DMA mask\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) err = pci_enable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) dev_err(dev, "Cannot enable PCI device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) err = pci_request_regions(pdev, DRV_MODULE_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) dev_err(dev, "Cannot obtain PCI resources\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) goto err_disable_pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) pci_set_master(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) if (!pci_endpoint_test_alloc_irq_vectors(test, irq_type)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) goto err_disable_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) base = pci_ioremap_bar(pdev, bar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) if (!base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) dev_err(dev, "Failed to read BAR%d\n", bar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) WARN_ON(bar == test_reg_bar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) test->bar[bar] = base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) test->base = test->bar[test_reg_bar];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) if (!test->base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) dev_err(dev, "Cannot perform PCI test without BAR%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) test_reg_bar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) goto err_iounmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) pci_set_drvdata(pdev, test);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) id = ida_simple_get(&pci_endpoint_test_ida, 0, 0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) if (id < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) err = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) dev_err(dev, "Unable to get id\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) goto err_iounmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) snprintf(name, sizeof(name), DRV_MODULE_NAME ".%d", id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) test->name = kstrdup(name, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) if (!test->name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) goto err_ida_remove;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) if (!pci_endpoint_test_request_irq(test)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) goto err_kfree_test_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) misc_device = &test->miscdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) misc_device->minor = MISC_DYNAMIC_MINOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) misc_device->name = kstrdup(name, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) if (!misc_device->name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) goto err_release_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) misc_device->fops = &pci_endpoint_test_fops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) err = misc_register(misc_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) dev_err(dev, "Failed to register device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) goto err_kfree_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) err_kfree_name:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) kfree(misc_device->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) err_release_irq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) pci_endpoint_test_release_irq(test);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) err_kfree_test_name:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) kfree(test->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) err_ida_remove:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) ida_simple_remove(&pci_endpoint_test_ida, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) err_iounmap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) if (test->bar[bar])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) pci_iounmap(pdev, test->bar[bar]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) err_disable_irq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) pci_endpoint_test_free_irq_vectors(test);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) pci_release_regions(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) err_disable_pdev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) pci_disable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) static void pci_endpoint_test_remove(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) enum pci_barno bar;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) struct pci_endpoint_test *test = pci_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) struct miscdevice *misc_device = &test->miscdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) if (sscanf(misc_device->name, DRV_MODULE_NAME ".%d", &id) != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) if (id < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) misc_deregister(&test->miscdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) kfree(misc_device->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) kfree(test->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) ida_simple_remove(&pci_endpoint_test_ida, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) if (test->bar[bar])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) pci_iounmap(pdev, test->bar[bar]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) pci_endpoint_test_release_irq(test);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) pci_endpoint_test_free_irq_vectors(test);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) pci_release_regions(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) pci_disable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) static const struct pci_endpoint_test_data default_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) .test_reg_bar = BAR_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) .alignment = SZ_4K,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) .irq_type = IRQ_TYPE_MSI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) static const struct pci_endpoint_test_data am654_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) .test_reg_bar = BAR_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) .alignment = SZ_64K,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) .irq_type = IRQ_TYPE_MSI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) static const struct pci_endpoint_test_data j721e_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) .alignment = 256,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) .irq_type = IRQ_TYPE_MSI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) static const struct pci_device_id pci_endpoint_test_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA74x),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) .driver_data = (kernel_ulong_t)&default_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA72x),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) .driver_data = (kernel_ulong_t)&default_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) { PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, 0x81c0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) .driver_data = (kernel_ulong_t)&default_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) { PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, PCI_DEVICE_ID_LS1088A),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) .driver_data = (kernel_ulong_t)&default_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) { PCI_DEVICE_DATA(SYNOPSYS, EDDA, NULL) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_AM654),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) .driver_data = (kernel_ulong_t)&am654_data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) { PCI_DEVICE(PCI_VENDOR_ID_RENESAS, PCI_DEVICE_ID_RENESAS_R8A774A1),},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) { PCI_DEVICE(PCI_VENDOR_ID_RENESAS, PCI_DEVICE_ID_RENESAS_R8A774B1),},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) { PCI_DEVICE(PCI_VENDOR_ID_RENESAS, PCI_DEVICE_ID_RENESAS_R8A774C0),},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) { PCI_DEVICE(PCI_VENDOR_ID_RENESAS, PCI_DEVICE_ID_RENESAS_R8A774E1),},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_J721E),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) .driver_data = (kernel_ulong_t)&j721e_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) MODULE_DEVICE_TABLE(pci, pci_endpoint_test_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) static struct pci_driver pci_endpoint_test_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) .name = DRV_MODULE_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) .id_table = pci_endpoint_test_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) .probe = pci_endpoint_test_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) .remove = pci_endpoint_test_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) module_pci_driver(pci_endpoint_test_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) MODULE_DESCRIPTION("PCI ENDPOINT TEST HOST DRIVER");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) MODULE_LICENSE("GPL v2");