2 * Test driver to test endpoint functionality
4 * Copyright (C) 2017 Texas Instruments
5 * Author: Kishon Vijay Abraham I <kishon@ti.com>
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 of
9 * the License as published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include <linux/crc32.h>
21 #include <linux/delay.h>
23 #include <linux/module.h>
24 #include <linux/slab.h>
25 #include <linux/pci_ids.h>
26 #include <linux/random.h>
28 #include <linux/pci-epc.h>
29 #include <linux/pci-epf.h>
30 #include <linux/pci_regs.h>
32 #define COMMAND_RAISE_LEGACY_IRQ BIT(0)
33 #define COMMAND_RAISE_MSI_IRQ BIT(1)
34 #define MSI_NUMBER_SHIFT 2
35 #define MSI_NUMBER_MASK (0x3f << MSI_NUMBER_SHIFT)
36 #define COMMAND_READ BIT(8)
37 #define COMMAND_WRITE BIT(9)
38 #define COMMAND_COPY BIT(10)
40 #define STATUS_READ_SUCCESS BIT(0)
41 #define STATUS_READ_FAIL BIT(1)
42 #define STATUS_WRITE_SUCCESS BIT(2)
43 #define STATUS_WRITE_FAIL BIT(3)
44 #define STATUS_COPY_SUCCESS BIT(4)
45 #define STATUS_COPY_FAIL BIT(5)
46 #define STATUS_IRQ_RAISED BIT(6)
47 #define STATUS_SRC_ADDR_INVALID BIT(7)
48 #define STATUS_DST_ADDR_INVALID BIT(8)
50 #define TIMER_RESOLUTION 1
52 static struct workqueue_struct *kpcitest_workqueue;
57 struct delayed_work cmd_handler;
60 struct pci_epf_test_reg {
70 static struct pci_epf_header test_header = {
71 .vendorid = PCI_ANY_ID,
72 .deviceid = PCI_ANY_ID,
73 .baseclass_code = PCI_CLASS_OTHERS,
74 .interrupt_pin = PCI_INTERRUPT_INTA,
77 static int bar_size[] = { 512, 1024, 16384, 131072, 1048576 };
79 static int pci_epf_test_copy(struct pci_epf_test *epf_test)
82 void __iomem *src_addr;
83 void __iomem *dst_addr;
84 phys_addr_t src_phys_addr;
85 phys_addr_t dst_phys_addr;
86 struct pci_epf *epf = epf_test->epf;
87 struct device *dev = &epf->dev;
88 struct pci_epc *epc = epf->epc;
89 struct pci_epf_test_reg *reg = epf_test->reg[0];
91 src_addr = pci_epc_mem_alloc_addr(epc, &src_phys_addr, reg->size);
93 dev_err(dev, "failed to allocate source address\n");
94 reg->status = STATUS_SRC_ADDR_INVALID;
99 ret = pci_epc_map_addr(epc, src_phys_addr, reg->src_addr, reg->size);
101 dev_err(dev, "failed to map source address\n");
102 reg->status = STATUS_SRC_ADDR_INVALID;
106 dst_addr = pci_epc_mem_alloc_addr(epc, &dst_phys_addr, reg->size);
108 dev_err(dev, "failed to allocate destination address\n");
109 reg->status = STATUS_DST_ADDR_INVALID;
111 goto err_src_map_addr;
114 ret = pci_epc_map_addr(epc, dst_phys_addr, reg->dst_addr, reg->size);
116 dev_err(dev, "failed to map destination address\n");
117 reg->status = STATUS_DST_ADDR_INVALID;
121 memcpy(dst_addr, src_addr, reg->size);
123 pci_epc_unmap_addr(epc, dst_phys_addr);
126 pci_epc_mem_free_addr(epc, dst_phys_addr, dst_addr, reg->size);
129 pci_epc_unmap_addr(epc, src_phys_addr);
132 pci_epc_mem_free_addr(epc, src_phys_addr, src_addr, reg->size);
138 static int pci_epf_test_read(struct pci_epf_test *epf_test)
141 void __iomem *src_addr;
144 phys_addr_t phys_addr;
145 struct pci_epf *epf = epf_test->epf;
146 struct device *dev = &epf->dev;
147 struct pci_epc *epc = epf->epc;
148 struct pci_epf_test_reg *reg = epf_test->reg[0];
150 src_addr = pci_epc_mem_alloc_addr(epc, &phys_addr, reg->size);
152 dev_err(dev, "failed to allocate address\n");
153 reg->status = STATUS_SRC_ADDR_INVALID;
158 ret = pci_epc_map_addr(epc, phys_addr, reg->src_addr, reg->size);
160 dev_err(dev, "failed to map address\n");
161 reg->status = STATUS_SRC_ADDR_INVALID;
165 buf = kzalloc(reg->size, GFP_KERNEL);
171 memcpy(buf, src_addr, reg->size);
173 crc32 = crc32_le(~0, buf, reg->size);
174 if (crc32 != reg->checksum)
180 pci_epc_unmap_addr(epc, phys_addr);
183 pci_epc_mem_free_addr(epc, phys_addr, src_addr, reg->size);
189 static int pci_epf_test_write(struct pci_epf_test *epf_test)
192 void __iomem *dst_addr;
194 phys_addr_t phys_addr;
195 struct pci_epf *epf = epf_test->epf;
196 struct device *dev = &epf->dev;
197 struct pci_epc *epc = epf->epc;
198 struct pci_epf_test_reg *reg = epf_test->reg[0];
200 dst_addr = pci_epc_mem_alloc_addr(epc, &phys_addr, reg->size);
202 dev_err(dev, "failed to allocate address\n");
203 reg->status = STATUS_DST_ADDR_INVALID;
208 ret = pci_epc_map_addr(epc, phys_addr, reg->dst_addr, reg->size);
210 dev_err(dev, "failed to map address\n");
211 reg->status = STATUS_DST_ADDR_INVALID;
215 buf = kzalloc(reg->size, GFP_KERNEL);
221 get_random_bytes(buf, reg->size);
222 reg->checksum = crc32_le(~0, buf, reg->size);
224 memcpy(dst_addr, buf, reg->size);
227 * wait 1ms inorder for the write to complete. Without this delay L3
228 * error in observed in the host system.
235 pci_epc_unmap_addr(epc, phys_addr);
238 pci_epc_mem_free_addr(epc, phys_addr, dst_addr, reg->size);
244 static void pci_epf_test_raise_irq(struct pci_epf_test *epf_test)
248 struct pci_epf *epf = epf_test->epf;
249 struct pci_epc *epc = epf->epc;
250 struct pci_epf_test_reg *reg = epf_test->reg[0];
252 reg->status |= STATUS_IRQ_RAISED;
253 msi_count = pci_epc_get_msi(epc);
254 irq = (reg->command & MSI_NUMBER_MASK) >> MSI_NUMBER_SHIFT;
255 if (irq > msi_count || msi_count <= 0)
256 pci_epc_raise_irq(epc, PCI_EPC_IRQ_LEGACY, 0);
258 pci_epc_raise_irq(epc, PCI_EPC_IRQ_MSI, irq);
261 static void pci_epf_test_cmd_handler(struct work_struct *work)
266 struct pci_epf_test *epf_test = container_of(work, struct pci_epf_test,
268 struct pci_epf *epf = epf_test->epf;
269 struct pci_epc *epc = epf->epc;
270 struct pci_epf_test_reg *reg = epf_test->reg[0];
275 if (reg->command & COMMAND_RAISE_LEGACY_IRQ) {
276 reg->status = STATUS_IRQ_RAISED;
277 pci_epc_raise_irq(epc, PCI_EPC_IRQ_LEGACY, 0);
281 if (reg->command & COMMAND_WRITE) {
282 ret = pci_epf_test_write(epf_test);
284 reg->status |= STATUS_WRITE_FAIL;
286 reg->status |= STATUS_WRITE_SUCCESS;
287 pci_epf_test_raise_irq(epf_test);
291 if (reg->command & COMMAND_READ) {
292 ret = pci_epf_test_read(epf_test);
294 reg->status |= STATUS_READ_SUCCESS;
296 reg->status |= STATUS_READ_FAIL;
297 pci_epf_test_raise_irq(epf_test);
301 if (reg->command & COMMAND_COPY) {
302 ret = pci_epf_test_copy(epf_test);
304 reg->status |= STATUS_COPY_SUCCESS;
306 reg->status |= STATUS_COPY_FAIL;
307 pci_epf_test_raise_irq(epf_test);
311 if (reg->command & COMMAND_RAISE_MSI_IRQ) {
312 msi_count = pci_epc_get_msi(epc);
313 irq = (reg->command & MSI_NUMBER_MASK) >> MSI_NUMBER_SHIFT;
314 if (irq > msi_count || msi_count <= 0)
316 reg->status = STATUS_IRQ_RAISED;
317 pci_epc_raise_irq(epc, PCI_EPC_IRQ_MSI, irq);
324 queue_delayed_work(kpcitest_workqueue, &epf_test->cmd_handler,
325 msecs_to_jiffies(1));
328 static void pci_epf_test_linkup(struct pci_epf *epf)
330 struct pci_epf_test *epf_test = epf_get_drvdata(epf);
332 queue_delayed_work(kpcitest_workqueue, &epf_test->cmd_handler,
333 msecs_to_jiffies(1));
336 static void pci_epf_test_unbind(struct pci_epf *epf)
338 struct pci_epf_test *epf_test = epf_get_drvdata(epf);
339 struct pci_epc *epc = epf->epc;
342 cancel_delayed_work(&epf_test->cmd_handler);
344 for (bar = BAR_0; bar <= BAR_5; bar++) {
345 if (epf_test->reg[bar]) {
346 pci_epf_free_space(epf, epf_test->reg[bar], bar);
347 pci_epc_clear_bar(epc, bar);
352 static int pci_epf_test_set_bar(struct pci_epf *epf)
357 struct pci_epf_bar *epf_bar;
358 struct pci_epc *epc = epf->epc;
359 struct device *dev = &epf->dev;
360 struct pci_epf_test *epf_test = epf_get_drvdata(epf);
362 flags = PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_32;
363 if (sizeof(dma_addr_t) == 0x8)
364 flags |= PCI_BASE_ADDRESS_MEM_TYPE_64;
366 for (bar = BAR_0; bar <= BAR_5; bar++) {
367 epf_bar = &epf->bar[bar];
368 ret = pci_epc_set_bar(epc, bar, epf_bar->phys_addr,
369 epf_bar->size, flags);
371 pci_epf_free_space(epf, epf_test->reg[bar], bar);
372 dev_err(dev, "failed to set BAR%d\n", bar);
381 static int pci_epf_test_alloc_space(struct pci_epf *epf)
383 struct pci_epf_test *epf_test = epf_get_drvdata(epf);
384 struct device *dev = &epf->dev;
388 base = pci_epf_alloc_space(epf, sizeof(struct pci_epf_test_reg),
391 dev_err(dev, "failed to allocated register space\n");
394 epf_test->reg[0] = base;
396 for (bar = BAR_1; bar <= BAR_5; bar++) {
397 base = pci_epf_alloc_space(epf, bar_size[bar - 1], bar);
399 dev_err(dev, "failed to allocate space for BAR%d\n",
401 epf_test->reg[bar] = base;
407 static int pci_epf_test_bind(struct pci_epf *epf)
410 struct pci_epf_header *header = epf->header;
411 struct pci_epc *epc = epf->epc;
412 struct device *dev = &epf->dev;
414 if (WARN_ON_ONCE(!epc))
417 ret = pci_epc_write_header(epc, header);
419 dev_err(dev, "configuration header write failed\n");
423 ret = pci_epf_test_alloc_space(epf);
427 ret = pci_epf_test_set_bar(epf);
431 ret = pci_epc_set_msi(epc, epf->msi_interrupts);
438 static int pci_epf_test_probe(struct pci_epf *epf)
440 struct pci_epf_test *epf_test;
441 struct device *dev = &epf->dev;
443 epf_test = devm_kzalloc(dev, sizeof(*epf_test), GFP_KERNEL);
447 epf->header = &test_header;
450 INIT_DELAYED_WORK(&epf_test->cmd_handler, pci_epf_test_cmd_handler);
452 epf_set_drvdata(epf, epf_test);
456 static int pci_epf_test_remove(struct pci_epf *epf)
458 struct pci_epf_test *epf_test = epf_get_drvdata(epf);
464 static struct pci_epf_ops ops = {
465 .unbind = pci_epf_test_unbind,
466 .bind = pci_epf_test_bind,
467 .linkup = pci_epf_test_linkup,
470 static const struct pci_epf_device_id pci_epf_test_ids[] = {
472 .name = "pci_epf_test",
477 static struct pci_epf_driver test_driver = {
478 .driver.name = "pci_epf_test",
479 .probe = pci_epf_test_probe,
480 .remove = pci_epf_test_remove,
481 .id_table = pci_epf_test_ids,
483 .owner = THIS_MODULE,
486 static int __init pci_epf_test_init(void)
490 kpcitest_workqueue = alloc_workqueue("kpcitest",
491 WQ_MEM_RECLAIM | WQ_HIGHPRI, 0);
492 ret = pci_epf_register_driver(&test_driver);
494 pr_err("failed to register pci epf test driver --> %d\n", ret);
500 module_init(pci_epf_test_init);
502 static void __exit pci_epf_test_exit(void)
504 pci_epf_unregister_driver(&test_driver);
506 module_exit(pci_epf_test_exit);
508 MODULE_DESCRIPTION("PCI EPF TEST DRIVER");
509 MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");
510 MODULE_LICENSE("GPL v2");