aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGustavo Pimentel <gustavo.pimentel@synopsys.com>2018-07-19 04:32:17 -0400
committerLorenzo Pieralisi <lorenzo.pieralisi@arm.com>2018-07-19 06:39:44 -0400
commite8817de7fbfca407f4f47da050d12b10fece5706 (patch)
tree855a301fca2b6b300747e6ca946d88f95886b7a5
parentcb22d40b5f2bcf9d374ae92ea504df620daea342 (diff)
pci-epf-test/pci_endpoint_test: Cleanup PCI_ENDPOINT_TEST memspace
Cleanup PCI_ENDPOINT_TEST memspace (by moving the interrupt number away from command section). Add IRQ_TYPE register to identify the triggered ID interrupt required for the READ/WRITE/COPY tests and raise IRQ test commands. Update documentation accordingly. Signed-off-by: Gustavo Pimentel <gustavo.pimentel@synopsys.com> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Acked-by: Kishon Vijay Abraham I <kishon@ti.com>
-rw-r--r--Documentation/PCI/endpoint/pci-test-function.txt27
-rw-r--r--drivers/misc/pci_endpoint_test.c81
-rw-r--r--drivers/pci/endpoint/functions/pci-epf-test.c61
3 files changed, 114 insertions, 55 deletions
diff --git a/Documentation/PCI/endpoint/pci-test-function.txt b/Documentation/PCI/endpoint/pci-test-function.txt
index 0c519c9bf94a..bf4b5cf6fee6 100644
--- a/Documentation/PCI/endpoint/pci-test-function.txt
+++ b/Documentation/PCI/endpoint/pci-test-function.txt
@@ -20,6 +20,8 @@ The PCI endpoint test device has the following registers:
20 5) PCI_ENDPOINT_TEST_DST_ADDR 20 5) PCI_ENDPOINT_TEST_DST_ADDR
21 6) PCI_ENDPOINT_TEST_SIZE 21 6) PCI_ENDPOINT_TEST_SIZE
22 7) PCI_ENDPOINT_TEST_CHECKSUM 22 7) PCI_ENDPOINT_TEST_CHECKSUM
23 8) PCI_ENDPOINT_TEST_IRQ_TYPE
24 9) PCI_ENDPOINT_TEST_IRQ_NUMBER
23 25
24*) PCI_ENDPOINT_TEST_MAGIC 26*) PCI_ENDPOINT_TEST_MAGIC
25 27
@@ -34,10 +36,10 @@ that the endpoint device must perform.
34Bitfield Description: 36Bitfield Description:
35 Bit 0 : raise legacy IRQ 37 Bit 0 : raise legacy IRQ
36 Bit 1 : raise MSI IRQ 38 Bit 1 : raise MSI IRQ
37 Bit 2 - 7 : MSI interrupt number 39 Bit 2 : raise MSI-X IRQ (reserved for future implementation)
38 Bit 8 : read command (read data from RC buffer) 40 Bit 3 : read command (read data from RC buffer)
39 Bit 9 : write command (write data to RC buffer) 41 Bit 4 : write command (write data to RC buffer)
40 Bit 10 : copy command (copy data from one RC buffer to another 42 Bit 5 : copy command (copy data from one RC buffer to another
41 RC buffer) 43 RC buffer)
42 44
43*) PCI_ENDPOINT_TEST_STATUS 45*) PCI_ENDPOINT_TEST_STATUS
@@ -64,3 +66,20 @@ COPY/READ command.
64 66
65This register contains the destination address (RC buffer address) for 67This register contains the destination address (RC buffer address) for
66the COPY/WRITE command. 68the COPY/WRITE command.
69
70*) PCI_ENDPOINT_TEST_IRQ_TYPE
71
72This register contains the interrupt type (Legacy/MSI) triggered
73for the READ/WRITE/COPY and raise IRQ (Legacy/MSI) commands.
74
75Possible types:
76 - Legacy : 0
77 - MSI : 1
78
79*) PCI_ENDPOINT_TEST_IRQ_NUMBER
80
81This register contains the triggered ID interrupt.
82
83Admissible values:
84 - Legacy : 0
85 - MSI : [1 .. 32]
diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
index 7b370466a227..35fbfbd73a6d 100644
--- a/drivers/misc/pci_endpoint_test.c
+++ b/drivers/misc/pci_endpoint_test.c
@@ -35,38 +35,43 @@
35 35
36#include <uapi/linux/pcitest.h> 36#include <uapi/linux/pcitest.h>
37 37
38#define DRV_MODULE_NAME "pci-endpoint-test" 38#define DRV_MODULE_NAME "pci-endpoint-test"
39 39
40#define PCI_ENDPOINT_TEST_MAGIC 0x0 40#define IRQ_TYPE_LEGACY 0
41 41#define IRQ_TYPE_MSI 1
42#define PCI_ENDPOINT_TEST_COMMAND 0x4 42
43#define COMMAND_RAISE_LEGACY_IRQ BIT(0) 43#define PCI_ENDPOINT_TEST_MAGIC 0x0
44#define COMMAND_RAISE_MSI_IRQ BIT(1) 44
45#define MSI_NUMBER_SHIFT 2 45#define PCI_ENDPOINT_TEST_COMMAND 0x4
46/* 6 bits for MSI number */ 46#define COMMAND_RAISE_LEGACY_IRQ BIT(0)
47#define COMMAND_READ BIT(8) 47#define COMMAND_RAISE_MSI_IRQ BIT(1)
48#define COMMAND_WRITE BIT(9) 48/* BIT(2) is reserved for raising MSI-X IRQ command */
49#define COMMAND_COPY BIT(10) 49#define COMMAND_READ BIT(3)
50 50#define COMMAND_WRITE BIT(4)
51#define PCI_ENDPOINT_TEST_STATUS 0x8 51#define COMMAND_COPY BIT(5)
52#define STATUS_READ_SUCCESS BIT(0) 52
53#define STATUS_READ_FAIL BIT(1) 53#define PCI_ENDPOINT_TEST_STATUS 0x8
54#define STATUS_WRITE_SUCCESS BIT(2) 54#define STATUS_READ_SUCCESS BIT(0)
55#define STATUS_WRITE_FAIL BIT(3) 55#define STATUS_READ_FAIL BIT(1)
56#define STATUS_COPY_SUCCESS BIT(4) 56#define STATUS_WRITE_SUCCESS BIT(2)
57#define STATUS_COPY_FAIL BIT(5) 57#define STATUS_WRITE_FAIL BIT(3)
58#define STATUS_IRQ_RAISED BIT(6) 58#define STATUS_COPY_SUCCESS BIT(4)
59#define STATUS_SRC_ADDR_INVALID BIT(7) 59#define STATUS_COPY_FAIL BIT(5)
60#define STATUS_DST_ADDR_INVALID BIT(8) 60#define STATUS_IRQ_RAISED BIT(6)
61 61#define STATUS_SRC_ADDR_INVALID BIT(7)
62#define PCI_ENDPOINT_TEST_LOWER_SRC_ADDR 0xc 62#define STATUS_DST_ADDR_INVALID BIT(8)
63
64#define PCI_ENDPOINT_TEST_LOWER_SRC_ADDR 0x0c
63#define PCI_ENDPOINT_TEST_UPPER_SRC_ADDR 0x10 65#define PCI_ENDPOINT_TEST_UPPER_SRC_ADDR 0x10
64 66
65#define PCI_ENDPOINT_TEST_LOWER_DST_ADDR 0x14 67#define PCI_ENDPOINT_TEST_LOWER_DST_ADDR 0x14
66#define PCI_ENDPOINT_TEST_UPPER_DST_ADDR 0x18 68#define PCI_ENDPOINT_TEST_UPPER_DST_ADDR 0x18
67 69
68#define PCI_ENDPOINT_TEST_SIZE 0x1c 70#define PCI_ENDPOINT_TEST_SIZE 0x1c
69#define PCI_ENDPOINT_TEST_CHECKSUM 0x20 71#define PCI_ENDPOINT_TEST_CHECKSUM 0x20
72
73#define PCI_ENDPOINT_TEST_IRQ_TYPE 0x24
74#define PCI_ENDPOINT_TEST_IRQ_NUMBER 0x28
70 75
71static DEFINE_IDA(pci_endpoint_test_ida); 76static DEFINE_IDA(pci_endpoint_test_ida);
72 77
@@ -179,6 +184,9 @@ static bool pci_endpoint_test_legacy_irq(struct pci_endpoint_test *test)
179{ 184{
180 u32 val; 185 u32 val;
181 186
187 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE,
188 IRQ_TYPE_LEGACY);
189 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 0);
182 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND, 190 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
183 COMMAND_RAISE_LEGACY_IRQ); 191 COMMAND_RAISE_LEGACY_IRQ);
184 val = wait_for_completion_timeout(&test->irq_raised, 192 val = wait_for_completion_timeout(&test->irq_raised,
@@ -195,8 +203,10 @@ static bool pci_endpoint_test_msi_irq(struct pci_endpoint_test *test,
195 u32 val; 203 u32 val;
196 struct pci_dev *pdev = test->pdev; 204 struct pci_dev *pdev = test->pdev;
197 205
206 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE,
207 IRQ_TYPE_MSI);
208 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, msi_num);
198 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND, 209 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
199 msi_num << MSI_NUMBER_SHIFT |
200 COMMAND_RAISE_MSI_IRQ); 210 COMMAND_RAISE_MSI_IRQ);
201 val = wait_for_completion_timeout(&test->irq_raised, 211 val = wait_for_completion_timeout(&test->irq_raised,
202 msecs_to_jiffies(1000)); 212 msecs_to_jiffies(1000));
@@ -281,8 +291,11 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test *test, size_t size)
281 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE, 291 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE,
282 size); 292 size);
283 293
294 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE,
295 no_msi ? IRQ_TYPE_LEGACY : IRQ_TYPE_MSI);
296 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
284 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND, 297 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
285 1 << MSI_NUMBER_SHIFT | COMMAND_COPY); 298 COMMAND_COPY);
286 299
287 wait_for_completion(&test->irq_raised); 300 wait_for_completion(&test->irq_raised);
288 301
@@ -348,8 +361,11 @@ static bool pci_endpoint_test_write(struct pci_endpoint_test *test, size_t size)
348 361
349 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE, size); 362 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE, size);
350 363
364 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE,
365 no_msi ? IRQ_TYPE_LEGACY : IRQ_TYPE_MSI);
366 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
351 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND, 367 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
352 1 << MSI_NUMBER_SHIFT | COMMAND_READ); 368 COMMAND_READ);
353 369
354 wait_for_completion(&test->irq_raised); 370 wait_for_completion(&test->irq_raised);
355 371
@@ -403,8 +419,11 @@ static bool pci_endpoint_test_read(struct pci_endpoint_test *test, size_t size)
403 419
404 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE, size); 420 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE, size);
405 421
422 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE,
423 no_msi ? IRQ_TYPE_LEGACY : IRQ_TYPE_MSI);
424 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
406 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND, 425 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
407 1 << MSI_NUMBER_SHIFT | COMMAND_WRITE); 426 COMMAND_WRITE);
408 427
409 wait_for_completion(&test->irq_raised); 428 wait_for_completion(&test->irq_raised);
410 429
diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
index 63ed706445b9..db4b23672004 100644
--- a/drivers/pci/endpoint/functions/pci-epf-test.c
+++ b/drivers/pci/endpoint/functions/pci-epf-test.c
@@ -18,13 +18,15 @@
18#include <linux/pci-epf.h> 18#include <linux/pci-epf.h>
19#include <linux/pci_regs.h> 19#include <linux/pci_regs.h>
20 20
21#define IRQ_TYPE_LEGACY 0
22#define IRQ_TYPE_MSI 1
23
21#define COMMAND_RAISE_LEGACY_IRQ BIT(0) 24#define COMMAND_RAISE_LEGACY_IRQ BIT(0)
22#define COMMAND_RAISE_MSI_IRQ BIT(1) 25#define COMMAND_RAISE_MSI_IRQ BIT(1)
23#define MSI_NUMBER_SHIFT 2 26/* BIT(2) is reserved for raising MSI-X IRQ command */
24#define MSI_NUMBER_MASK (0x3f << MSI_NUMBER_SHIFT) 27#define COMMAND_READ BIT(3)
25#define COMMAND_READ BIT(8) 28#define COMMAND_WRITE BIT(4)
26#define COMMAND_WRITE BIT(9) 29#define COMMAND_COPY BIT(5)
27#define COMMAND_COPY BIT(10)
28 30
29#define STATUS_READ_SUCCESS BIT(0) 31#define STATUS_READ_SUCCESS BIT(0)
30#define STATUS_READ_FAIL BIT(1) 32#define STATUS_READ_FAIL BIT(1)
@@ -56,6 +58,8 @@ struct pci_epf_test_reg {
56 u64 dst_addr; 58 u64 dst_addr;
57 u32 size; 59 u32 size;
58 u32 checksum; 60 u32 checksum;
61 u32 irq_type;
62 u32 irq_number;
59} __packed; 63} __packed;
60 64
61static struct pci_epf_header test_header = { 65static struct pci_epf_header test_header = {
@@ -244,31 +248,39 @@ err:
244 return ret; 248 return ret;
245} 249}
246 250
247static void pci_epf_test_raise_irq(struct pci_epf_test *epf_test, u8 irq) 251static void pci_epf_test_raise_irq(struct pci_epf_test *epf_test, u8 irq_type,
252 u16 irq)
248{ 253{
249 u8 msi_count;
250 struct pci_epf *epf = epf_test->epf; 254 struct pci_epf *epf = epf_test->epf;
255 struct device *dev = &epf->dev;
251 struct pci_epc *epc = epf->epc; 256 struct pci_epc *epc = epf->epc;
252 enum pci_barno test_reg_bar = epf_test->test_reg_bar; 257 enum pci_barno test_reg_bar = epf_test->test_reg_bar;
253 struct pci_epf_test_reg *reg = epf_test->reg[test_reg_bar]; 258 struct pci_epf_test_reg *reg = epf_test->reg[test_reg_bar];
254 259
255 reg->status |= STATUS_IRQ_RAISED; 260 reg->status |= STATUS_IRQ_RAISED;
256 msi_count = pci_epc_get_msi(epc, epf->func_no); 261
257 if (irq > msi_count || msi_count <= 0) 262 switch (irq_type) {
263 case IRQ_TYPE_LEGACY:
258 pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_LEGACY, 0); 264 pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_LEGACY, 0);
259 else 265 break;
266 case IRQ_TYPE_MSI:
260 pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_MSI, irq); 267 pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_MSI, irq);
268 break;
269 default:
270 dev_err(dev, "Failed to raise IRQ, unknown type\n");
271 break;
272 }
261} 273}
262 274
263static void pci_epf_test_cmd_handler(struct work_struct *work) 275static void pci_epf_test_cmd_handler(struct work_struct *work)
264{ 276{
265 int ret; 277 int ret;
266 u8 irq; 278 int count;
267 u8 msi_count;
268 u32 command; 279 u32 command;
269 struct pci_epf_test *epf_test = container_of(work, struct pci_epf_test, 280 struct pci_epf_test *epf_test = container_of(work, struct pci_epf_test,
270 cmd_handler.work); 281 cmd_handler.work);
271 struct pci_epf *epf = epf_test->epf; 282 struct pci_epf *epf = epf_test->epf;
283 struct device *dev = &epf->dev;
272 struct pci_epc *epc = epf->epc; 284 struct pci_epc *epc = epf->epc;
273 enum pci_barno test_reg_bar = epf_test->test_reg_bar; 285 enum pci_barno test_reg_bar = epf_test->test_reg_bar;
274 struct pci_epf_test_reg *reg = epf_test->reg[test_reg_bar]; 286 struct pci_epf_test_reg *reg = epf_test->reg[test_reg_bar];
@@ -280,7 +292,10 @@ static void pci_epf_test_cmd_handler(struct work_struct *work)
280 reg->command = 0; 292 reg->command = 0;
281 reg->status = 0; 293 reg->status = 0;
282 294
283 irq = (command & MSI_NUMBER_MASK) >> MSI_NUMBER_SHIFT; 295 if (reg->irq_type > IRQ_TYPE_MSI) {
296 dev_err(dev, "Failed to detect IRQ type\n");
297 goto reset_handler;
298 }
284 299
285 if (command & COMMAND_RAISE_LEGACY_IRQ) { 300 if (command & COMMAND_RAISE_LEGACY_IRQ) {
286 reg->status = STATUS_IRQ_RAISED; 301 reg->status = STATUS_IRQ_RAISED;
@@ -294,7 +309,8 @@ static void pci_epf_test_cmd_handler(struct work_struct *work)
294 reg->status |= STATUS_WRITE_FAIL; 309 reg->status |= STATUS_WRITE_FAIL;
295 else 310 else
296 reg->status |= STATUS_WRITE_SUCCESS; 311 reg->status |= STATUS_WRITE_SUCCESS;
297 pci_epf_test_raise_irq(epf_test, irq); 312 pci_epf_test_raise_irq(epf_test, reg->irq_type,
313 reg->irq_number);
298 goto reset_handler; 314 goto reset_handler;
299 } 315 }
300 316
@@ -304,7 +320,8 @@ static void pci_epf_test_cmd_handler(struct work_struct *work)
304 reg->status |= STATUS_READ_SUCCESS; 320 reg->status |= STATUS_READ_SUCCESS;
305 else 321 else
306 reg->status |= STATUS_READ_FAIL; 322 reg->status |= STATUS_READ_FAIL;
307 pci_epf_test_raise_irq(epf_test, irq); 323 pci_epf_test_raise_irq(epf_test, reg->irq_type,
324 reg->irq_number);
308 goto reset_handler; 325 goto reset_handler;
309 } 326 }
310 327
@@ -314,16 +331,18 @@ static void pci_epf_test_cmd_handler(struct work_struct *work)
314 reg->status |= STATUS_COPY_SUCCESS; 331 reg->status |= STATUS_COPY_SUCCESS;
315 else 332 else
316 reg->status |= STATUS_COPY_FAIL; 333 reg->status |= STATUS_COPY_FAIL;
317 pci_epf_test_raise_irq(epf_test, irq); 334 pci_epf_test_raise_irq(epf_test, reg->irq_type,
335 reg->irq_number);
318 goto reset_handler; 336 goto reset_handler;
319 } 337 }
320 338
321 if (command & COMMAND_RAISE_MSI_IRQ) { 339 if (command & COMMAND_RAISE_MSI_IRQ) {
322 msi_count = pci_epc_get_msi(epc, epf->func_no); 340 count = pci_epc_get_msi(epc, epf->func_no);
323 if (irq > msi_count || msi_count <= 0) 341 if (reg->irq_number > count || count <= 0)
324 goto reset_handler; 342 goto reset_handler;
325 reg->status = STATUS_IRQ_RAISED; 343 reg->status = STATUS_IRQ_RAISED;
326 pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_MSI, irq); 344 pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_MSI,
345 reg->irq_number);
327 goto reset_handler; 346 goto reset_handler;
328 } 347 }
329 348
@@ -457,8 +476,10 @@ static int pci_epf_test_bind(struct pci_epf *epf)
457 return ret; 476 return ret;
458 477
459 ret = pci_epc_set_msi(epc, epf->func_no, epf->msi_interrupts); 478 ret = pci_epc_set_msi(epc, epf->func_no, epf->msi_interrupts);
460 if (ret) 479 if (ret) {
480 dev_err(dev, "MSI configuration failed\n");
461 return ret; 481 return ret;
482 }
462 483
463 if (!epf_test->linkup_notifier) 484 if (!epf_test->linkup_notifier)
464 queue_work(kpcitest_workqueue, &epf_test->cmd_handler.work); 485 queue_work(kpcitest_workqueue, &epf_test->cmd_handler.work);