]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/pci/endpoint/functions/pci-epf-test.c
Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
[karo-tx-linux.git] / drivers / pci / endpoint / functions / pci-epf-test.c
1 /**
2  * Test driver to test endpoint functionality
3  *
4  * Copyright (C) 2017 Texas Instruments
5  * Author: Kishon Vijay Abraham I <kishon@ti.com>
6  *
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.
10  *
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.
15  *
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/>.
18  */
19
20 #include <linux/crc32.h>
21 #include <linux/delay.h>
22 #include <linux/io.h>
23 #include <linux/module.h>
24 #include <linux/slab.h>
25 #include <linux/pci_ids.h>
26 #include <linux/random.h>
27
28 #include <linux/pci-epc.h>
29 #include <linux/pci-epf.h>
30 #include <linux/pci_regs.h>
31
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)
39
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)
49
50 #define TIMER_RESOLUTION                1
51
52 static struct workqueue_struct *kpcitest_workqueue;
53
54 struct pci_epf_test {
55         void                    *reg[6];
56         struct pci_epf          *epf;
57         struct delayed_work     cmd_handler;
58 };
59
60 struct pci_epf_test_reg {
61         u32     magic;
62         u32     command;
63         u32     status;
64         u64     src_addr;
65         u64     dst_addr;
66         u32     size;
67         u32     checksum;
68 } __packed;
69
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,
75 };
76
77 static int bar_size[] = { 512, 1024, 16384, 131072, 1048576 };
78
79 static int pci_epf_test_copy(struct pci_epf_test *epf_test)
80 {
81         int ret;
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];
90
91         src_addr = pci_epc_mem_alloc_addr(epc, &src_phys_addr, reg->size);
92         if (!src_addr) {
93                 dev_err(dev, "failed to allocate source address\n");
94                 reg->status = STATUS_SRC_ADDR_INVALID;
95                 ret = -ENOMEM;
96                 goto err;
97         }
98
99         ret = pci_epc_map_addr(epc, src_phys_addr, reg->src_addr, reg->size);
100         if (ret) {
101                 dev_err(dev, "failed to map source address\n");
102                 reg->status = STATUS_SRC_ADDR_INVALID;
103                 goto err_src_addr;
104         }
105
106         dst_addr = pci_epc_mem_alloc_addr(epc, &dst_phys_addr, reg->size);
107         if (!dst_addr) {
108                 dev_err(dev, "failed to allocate destination address\n");
109                 reg->status = STATUS_DST_ADDR_INVALID;
110                 ret = -ENOMEM;
111                 goto err_src_map_addr;
112         }
113
114         ret = pci_epc_map_addr(epc, dst_phys_addr, reg->dst_addr, reg->size);
115         if (ret) {
116                 dev_err(dev, "failed to map destination address\n");
117                 reg->status = STATUS_DST_ADDR_INVALID;
118                 goto err_dst_addr;
119         }
120
121         memcpy(dst_addr, src_addr, reg->size);
122
123         pci_epc_unmap_addr(epc, dst_phys_addr);
124
125 err_dst_addr:
126         pci_epc_mem_free_addr(epc, dst_phys_addr, dst_addr, reg->size);
127
128 err_src_map_addr:
129         pci_epc_unmap_addr(epc, src_phys_addr);
130
131 err_src_addr:
132         pci_epc_mem_free_addr(epc, src_phys_addr, src_addr, reg->size);
133
134 err:
135         return ret;
136 }
137
138 static int pci_epf_test_read(struct pci_epf_test *epf_test)
139 {
140         int ret;
141         void __iomem *src_addr;
142         void *buf;
143         u32 crc32;
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];
149
150         src_addr = pci_epc_mem_alloc_addr(epc, &phys_addr, reg->size);
151         if (!src_addr) {
152                 dev_err(dev, "failed to allocate address\n");
153                 reg->status = STATUS_SRC_ADDR_INVALID;
154                 ret = -ENOMEM;
155                 goto err;
156         }
157
158         ret = pci_epc_map_addr(epc, phys_addr, reg->src_addr, reg->size);
159         if (ret) {
160                 dev_err(dev, "failed to map address\n");
161                 reg->status = STATUS_SRC_ADDR_INVALID;
162                 goto err_addr;
163         }
164
165         buf = kzalloc(reg->size, GFP_KERNEL);
166         if (!buf) {
167                 ret = -ENOMEM;
168                 goto err_map_addr;
169         }
170
171         memcpy(buf, src_addr, reg->size);
172
173         crc32 = crc32_le(~0, buf, reg->size);
174         if (crc32 != reg->checksum)
175                 ret = -EIO;
176
177         kfree(buf);
178
179 err_map_addr:
180         pci_epc_unmap_addr(epc, phys_addr);
181
182 err_addr:
183         pci_epc_mem_free_addr(epc, phys_addr, src_addr, reg->size);
184
185 err:
186         return ret;
187 }
188
189 static int pci_epf_test_write(struct pci_epf_test *epf_test)
190 {
191         int ret;
192         void __iomem *dst_addr;
193         void *buf;
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];
199
200         dst_addr = pci_epc_mem_alloc_addr(epc, &phys_addr, reg->size);
201         if (!dst_addr) {
202                 dev_err(dev, "failed to allocate address\n");
203                 reg->status = STATUS_DST_ADDR_INVALID;
204                 ret = -ENOMEM;
205                 goto err;
206         }
207
208         ret = pci_epc_map_addr(epc, phys_addr, reg->dst_addr, reg->size);
209         if (ret) {
210                 dev_err(dev, "failed to map address\n");
211                 reg->status = STATUS_DST_ADDR_INVALID;
212                 goto err_addr;
213         }
214
215         buf = kzalloc(reg->size, GFP_KERNEL);
216         if (!buf) {
217                 ret = -ENOMEM;
218                 goto err_map_addr;
219         }
220
221         get_random_bytes(buf, reg->size);
222         reg->checksum = crc32_le(~0, buf, reg->size);
223
224         memcpy(dst_addr, buf, reg->size);
225
226         /*
227          * wait 1ms inorder for the write to complete. Without this delay L3
228          * error in observed in the host system.
229          */
230         mdelay(1);
231
232         kfree(buf);
233
234 err_map_addr:
235         pci_epc_unmap_addr(epc, phys_addr);
236
237 err_addr:
238         pci_epc_mem_free_addr(epc, phys_addr, dst_addr, reg->size);
239
240 err:
241         return ret;
242 }
243
244 static void pci_epf_test_raise_irq(struct pci_epf_test *epf_test)
245 {
246         u8 irq;
247         u8 msi_count;
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];
251
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);
257         else
258                 pci_epc_raise_irq(epc, PCI_EPC_IRQ_MSI, irq);
259 }
260
261 static void pci_epf_test_cmd_handler(struct work_struct *work)
262 {
263         int ret;
264         u8 irq;
265         u8 msi_count;
266         struct pci_epf_test *epf_test = container_of(work, struct pci_epf_test,
267                                                      cmd_handler.work);
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];
271
272         if (!reg->command)
273                 goto reset_handler;
274
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);
278                 goto reset_handler;
279         }
280
281         if (reg->command & COMMAND_WRITE) {
282                 ret = pci_epf_test_write(epf_test);
283                 if (ret)
284                         reg->status |= STATUS_WRITE_FAIL;
285                 else
286                         reg->status |= STATUS_WRITE_SUCCESS;
287                 pci_epf_test_raise_irq(epf_test);
288                 goto reset_handler;
289         }
290
291         if (reg->command & COMMAND_READ) {
292                 ret = pci_epf_test_read(epf_test);
293                 if (!ret)
294                         reg->status |= STATUS_READ_SUCCESS;
295                 else
296                         reg->status |= STATUS_READ_FAIL;
297                 pci_epf_test_raise_irq(epf_test);
298                 goto reset_handler;
299         }
300
301         if (reg->command & COMMAND_COPY) {
302                 ret = pci_epf_test_copy(epf_test);
303                 if (!ret)
304                         reg->status |= STATUS_COPY_SUCCESS;
305                 else
306                         reg->status |= STATUS_COPY_FAIL;
307                 pci_epf_test_raise_irq(epf_test);
308                 goto reset_handler;
309         }
310
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)
315                         goto reset_handler;
316                 reg->status = STATUS_IRQ_RAISED;
317                 pci_epc_raise_irq(epc, PCI_EPC_IRQ_MSI, irq);
318                 goto reset_handler;
319         }
320
321 reset_handler:
322         reg->command = 0;
323
324         queue_delayed_work(kpcitest_workqueue, &epf_test->cmd_handler,
325                            msecs_to_jiffies(1));
326 }
327
328 static void pci_epf_test_linkup(struct pci_epf *epf)
329 {
330         struct pci_epf_test *epf_test = epf_get_drvdata(epf);
331
332         queue_delayed_work(kpcitest_workqueue, &epf_test->cmd_handler,
333                            msecs_to_jiffies(1));
334 }
335
336 static void pci_epf_test_unbind(struct pci_epf *epf)
337 {
338         struct pci_epf_test *epf_test = epf_get_drvdata(epf);
339         struct pci_epc *epc = epf->epc;
340         int bar;
341
342         cancel_delayed_work(&epf_test->cmd_handler);
343         pci_epc_stop(epc);
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);
348                 }
349         }
350 }
351
352 static int pci_epf_test_set_bar(struct pci_epf *epf)
353 {
354         int flags;
355         int bar;
356         int ret;
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);
361
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;
365
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);
370                 if (ret) {
371                         pci_epf_free_space(epf, epf_test->reg[bar], bar);
372                         dev_err(dev, "failed to set BAR%d\n", bar);
373                         if (bar == BAR_0)
374                                 return ret;
375                 }
376         }
377
378         return 0;
379 }
380
381 static int pci_epf_test_alloc_space(struct pci_epf *epf)
382 {
383         struct pci_epf_test *epf_test = epf_get_drvdata(epf);
384         struct device *dev = &epf->dev;
385         void *base;
386         int bar;
387
388         base = pci_epf_alloc_space(epf, sizeof(struct pci_epf_test_reg),
389                                    BAR_0);
390         if (!base) {
391                 dev_err(dev, "failed to allocated register space\n");
392                 return -ENOMEM;
393         }
394         epf_test->reg[0] = base;
395
396         for (bar = BAR_1; bar <= BAR_5; bar++) {
397                 base = pci_epf_alloc_space(epf, bar_size[bar - 1], bar);
398                 if (!base)
399                         dev_err(dev, "failed to allocate space for BAR%d\n",
400                                 bar);
401                 epf_test->reg[bar] = base;
402         }
403
404         return 0;
405 }
406
407 static int pci_epf_test_bind(struct pci_epf *epf)
408 {
409         int ret;
410         struct pci_epf_header *header = epf->header;
411         struct pci_epc *epc = epf->epc;
412         struct device *dev = &epf->dev;
413
414         if (WARN_ON_ONCE(!epc))
415                 return -EINVAL;
416
417         ret = pci_epc_write_header(epc, header);
418         if (ret) {
419                 dev_err(dev, "configuration header write failed\n");
420                 return ret;
421         }
422
423         ret = pci_epf_test_alloc_space(epf);
424         if (ret)
425                 return ret;
426
427         ret = pci_epf_test_set_bar(epf);
428         if (ret)
429                 return ret;
430
431         ret = pci_epc_set_msi(epc, epf->msi_interrupts);
432         if (ret)
433                 return ret;
434
435         return 0;
436 }
437
438 static int pci_epf_test_probe(struct pci_epf *epf)
439 {
440         struct pci_epf_test *epf_test;
441         struct device *dev = &epf->dev;
442
443         epf_test = devm_kzalloc(dev, sizeof(*epf_test), GFP_KERNEL);
444         if (!epf_test)
445                 return -ENOMEM;
446
447         epf->header = &test_header;
448         epf_test->epf = epf;
449
450         INIT_DELAYED_WORK(&epf_test->cmd_handler, pci_epf_test_cmd_handler);
451
452         epf_set_drvdata(epf, epf_test);
453         return 0;
454 }
455
456 static int pci_epf_test_remove(struct pci_epf *epf)
457 {
458         struct pci_epf_test *epf_test = epf_get_drvdata(epf);
459
460         kfree(epf_test);
461         return 0;
462 }
463
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,
468 };
469
470 static const struct pci_epf_device_id pci_epf_test_ids[] = {
471         {
472                 .name = "pci_epf_test",
473         },
474         {},
475 };
476
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,
482         .ops            = &ops,
483         .owner          = THIS_MODULE,
484 };
485
486 static int __init pci_epf_test_init(void)
487 {
488         int ret;
489
490         kpcitest_workqueue = alloc_workqueue("kpcitest",
491                                              WQ_MEM_RECLAIM | WQ_HIGHPRI, 0);
492         ret = pci_epf_register_driver(&test_driver);
493         if (ret) {
494                 pr_err("failed to register pci epf test driver --> %d\n", ret);
495                 return ret;
496         }
497
498         return 0;
499 }
500 module_init(pci_epf_test_init);
501
502 static void __exit pci_epf_test_exit(void)
503 {
504         pci_epf_unregister_driver(&test_driver);
505 }
506 module_exit(pci_epf_test_exit);
507
508 MODULE_DESCRIPTION("PCI EPF TEST DRIVER");
509 MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");
510 MODULE_LICENSE("GPL v2");