1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42#include <linux/stddef.h>
43#include <linux/types.h>
44#include <linux/kernel.h>
45#include <linux/bitops.h>
46#include <linux/sizes.h>
47#include <linux/module.h>
48#include <linux/moduleparam.h>
49#include <linux/init.h>
50#include <linux/interrupt.h>
51#include <linux/spinlock.h>
52#include <linux/pci.h>
53#include <linux/aer.h>
54#include <linux/slab.h>
55#include <linux/list.h>
56#include <linux/debugfs.h>
57#include <linux/ntb.h>
58
59#include "ntb_hw_idt.h"
60
61#define NTB_NAME "ntb_hw_idt"
62#define NTB_DESC "IDT PCI-E Non-Transparent Bridge Driver"
63#define NTB_VER "2.0"
64#define NTB_IRQNAME "ntb_irq_idt"
65
66MODULE_DESCRIPTION(NTB_DESC);
67MODULE_VERSION(NTB_VER);
68MODULE_LICENSE("GPL v2");
69MODULE_AUTHOR("T-platforms");
70
71
72
73
74
75static const struct idt_ntb_regs ntdata_tbl = {
76 { {IDT_NT_BARSETUP0, IDT_NT_BARLIMIT0,
77 IDT_NT_BARLTBASE0, IDT_NT_BARUTBASE0},
78 {IDT_NT_BARSETUP1, IDT_NT_BARLIMIT1,
79 IDT_NT_BARLTBASE1, IDT_NT_BARUTBASE1},
80 {IDT_NT_BARSETUP2, IDT_NT_BARLIMIT2,
81 IDT_NT_BARLTBASE2, IDT_NT_BARUTBASE2},
82 {IDT_NT_BARSETUP3, IDT_NT_BARLIMIT3,
83 IDT_NT_BARLTBASE3, IDT_NT_BARUTBASE3},
84 {IDT_NT_BARSETUP4, IDT_NT_BARLIMIT4,
85 IDT_NT_BARLTBASE4, IDT_NT_BARUTBASE4},
86 {IDT_NT_BARSETUP5, IDT_NT_BARLIMIT5,
87 IDT_NT_BARLTBASE5, IDT_NT_BARUTBASE5} },
88 { {IDT_NT_INMSG0, IDT_NT_OUTMSG0, IDT_NT_INMSGSRC0},
89 {IDT_NT_INMSG1, IDT_NT_OUTMSG1, IDT_NT_INMSGSRC1},
90 {IDT_NT_INMSG2, IDT_NT_OUTMSG2, IDT_NT_INMSGSRC2},
91 {IDT_NT_INMSG3, IDT_NT_OUTMSG3, IDT_NT_INMSGSRC3} }
92};
93
94
95
96
97
98static const struct idt_ntb_port portdata_tbl[IDT_MAX_NR_PORTS] = {
99 { IDT_SW_NTP0_PCIECMDSTS, IDT_SW_NTP0_PCIELCTLSTS,
100 IDT_SW_NTP0_NTCTL,
101 IDT_SW_SWPORT0CTL, IDT_SW_SWPORT0STS,
102 { {IDT_SW_NTP0_BARSETUP0, IDT_SW_NTP0_BARLIMIT0,
103 IDT_SW_NTP0_BARLTBASE0, IDT_SW_NTP0_BARUTBASE0},
104 {IDT_SW_NTP0_BARSETUP1, IDT_SW_NTP0_BARLIMIT1,
105 IDT_SW_NTP0_BARLTBASE1, IDT_SW_NTP0_BARUTBASE1},
106 {IDT_SW_NTP0_BARSETUP2, IDT_SW_NTP0_BARLIMIT2,
107 IDT_SW_NTP0_BARLTBASE2, IDT_SW_NTP0_BARUTBASE2},
108 {IDT_SW_NTP0_BARSETUP3, IDT_SW_NTP0_BARLIMIT3,
109 IDT_SW_NTP0_BARLTBASE3, IDT_SW_NTP0_BARUTBASE3},
110 {IDT_SW_NTP0_BARSETUP4, IDT_SW_NTP0_BARLIMIT4,
111 IDT_SW_NTP0_BARLTBASE4, IDT_SW_NTP0_BARUTBASE4},
112 {IDT_SW_NTP0_BARSETUP5, IDT_SW_NTP0_BARLIMIT5,
113 IDT_SW_NTP0_BARLTBASE5, IDT_SW_NTP0_BARUTBASE5} } },
114 {0},
115 { IDT_SW_NTP2_PCIECMDSTS, IDT_SW_NTP2_PCIELCTLSTS,
116 IDT_SW_NTP2_NTCTL,
117 IDT_SW_SWPORT2CTL, IDT_SW_SWPORT2STS,
118 { {IDT_SW_NTP2_BARSETUP0, IDT_SW_NTP2_BARLIMIT0,
119 IDT_SW_NTP2_BARLTBASE0, IDT_SW_NTP2_BARUTBASE0},
120 {IDT_SW_NTP2_BARSETUP1, IDT_SW_NTP2_BARLIMIT1,
121 IDT_SW_NTP2_BARLTBASE1, IDT_SW_NTP2_BARUTBASE1},
122 {IDT_SW_NTP2_BARSETUP2, IDT_SW_NTP2_BARLIMIT2,
123 IDT_SW_NTP2_BARLTBASE2, IDT_SW_NTP2_BARUTBASE2},
124 {IDT_SW_NTP2_BARSETUP3, IDT_SW_NTP2_BARLIMIT3,
125 IDT_SW_NTP2_BARLTBASE3, IDT_SW_NTP2_BARUTBASE3},
126 {IDT_SW_NTP2_BARSETUP4, IDT_SW_NTP2_BARLIMIT4,
127 IDT_SW_NTP2_BARLTBASE4, IDT_SW_NTP2_BARUTBASE4},
128 {IDT_SW_NTP2_BARSETUP5, IDT_SW_NTP2_BARLIMIT5,
129 IDT_SW_NTP2_BARLTBASE5, IDT_SW_NTP2_BARUTBASE5} } },
130 {0},
131 { IDT_SW_NTP4_PCIECMDSTS, IDT_SW_NTP4_PCIELCTLSTS,
132 IDT_SW_NTP4_NTCTL,
133 IDT_SW_SWPORT4CTL, IDT_SW_SWPORT4STS,
134 { {IDT_SW_NTP4_BARSETUP0, IDT_SW_NTP4_BARLIMIT0,
135 IDT_SW_NTP4_BARLTBASE0, IDT_SW_NTP4_BARUTBASE0},
136 {IDT_SW_NTP4_BARSETUP1, IDT_SW_NTP4_BARLIMIT1,
137 IDT_SW_NTP4_BARLTBASE1, IDT_SW_NTP4_BARUTBASE1},
138 {IDT_SW_NTP4_BARSETUP2, IDT_SW_NTP4_BARLIMIT2,
139 IDT_SW_NTP4_BARLTBASE2, IDT_SW_NTP4_BARUTBASE2},
140 {IDT_SW_NTP4_BARSETUP3, IDT_SW_NTP4_BARLIMIT3,
141 IDT_SW_NTP4_BARLTBASE3, IDT_SW_NTP4_BARUTBASE3},
142 {IDT_SW_NTP4_BARSETUP4, IDT_SW_NTP4_BARLIMIT4,
143 IDT_SW_NTP4_BARLTBASE4, IDT_SW_NTP4_BARUTBASE4},
144 {IDT_SW_NTP4_BARSETUP5, IDT_SW_NTP4_BARLIMIT5,
145 IDT_SW_NTP4_BARLTBASE5, IDT_SW_NTP4_BARUTBASE5} } },
146 {0},
147 { IDT_SW_NTP6_PCIECMDSTS, IDT_SW_NTP6_PCIELCTLSTS,
148 IDT_SW_NTP6_NTCTL,
149 IDT_SW_SWPORT6CTL, IDT_SW_SWPORT6STS,
150 { {IDT_SW_NTP6_BARSETUP0, IDT_SW_NTP6_BARLIMIT0,
151 IDT_SW_NTP6_BARLTBASE0, IDT_SW_NTP6_BARUTBASE0},
152 {IDT_SW_NTP6_BARSETUP1, IDT_SW_NTP6_BARLIMIT1,
153 IDT_SW_NTP6_BARLTBASE1, IDT_SW_NTP6_BARUTBASE1},
154 {IDT_SW_NTP6_BARSETUP2, IDT_SW_NTP6_BARLIMIT2,
155 IDT_SW_NTP6_BARLTBASE2, IDT_SW_NTP6_BARUTBASE2},
156 {IDT_SW_NTP6_BARSETUP3, IDT_SW_NTP6_BARLIMIT3,
157 IDT_SW_NTP6_BARLTBASE3, IDT_SW_NTP6_BARUTBASE3},
158 {IDT_SW_NTP6_BARSETUP4, IDT_SW_NTP6_BARLIMIT4,
159 IDT_SW_NTP6_BARLTBASE4, IDT_SW_NTP6_BARUTBASE4},
160 {IDT_SW_NTP6_BARSETUP5, IDT_SW_NTP6_BARLIMIT5,
161 IDT_SW_NTP6_BARLTBASE5, IDT_SW_NTP6_BARUTBASE5} } },
162 {0},
163 { IDT_SW_NTP8_PCIECMDSTS, IDT_SW_NTP8_PCIELCTLSTS,
164 IDT_SW_NTP8_NTCTL,
165 IDT_SW_SWPORT8CTL, IDT_SW_SWPORT8STS,
166 { {IDT_SW_NTP8_BARSETUP0, IDT_SW_NTP8_BARLIMIT0,
167 IDT_SW_NTP8_BARLTBASE0, IDT_SW_NTP8_BARUTBASE0},
168 {IDT_SW_NTP8_BARSETUP1, IDT_SW_NTP8_BARLIMIT1,
169 IDT_SW_NTP8_BARLTBASE1, IDT_SW_NTP8_BARUTBASE1},
170 {IDT_SW_NTP8_BARSETUP2, IDT_SW_NTP8_BARLIMIT2,
171 IDT_SW_NTP8_BARLTBASE2, IDT_SW_NTP8_BARUTBASE2},
172 {IDT_SW_NTP8_BARSETUP3, IDT_SW_NTP8_BARLIMIT3,
173 IDT_SW_NTP8_BARLTBASE3, IDT_SW_NTP8_BARUTBASE3},
174 {IDT_SW_NTP8_BARSETUP4, IDT_SW_NTP8_BARLIMIT4,
175 IDT_SW_NTP8_BARLTBASE4, IDT_SW_NTP8_BARUTBASE4},
176 {IDT_SW_NTP8_BARSETUP5, IDT_SW_NTP8_BARLIMIT5,
177 IDT_SW_NTP8_BARLTBASE5, IDT_SW_NTP8_BARUTBASE5} } },
178 {0},
179 {0},
180 {0},
181 { IDT_SW_NTP12_PCIECMDSTS, IDT_SW_NTP12_PCIELCTLSTS,
182 IDT_SW_NTP12_NTCTL,
183 IDT_SW_SWPORT12CTL, IDT_SW_SWPORT12STS,
184 { {IDT_SW_NTP12_BARSETUP0, IDT_SW_NTP12_BARLIMIT0,
185 IDT_SW_NTP12_BARLTBASE0, IDT_SW_NTP12_BARUTBASE0},
186 {IDT_SW_NTP12_BARSETUP1, IDT_SW_NTP12_BARLIMIT1,
187 IDT_SW_NTP12_BARLTBASE1, IDT_SW_NTP12_BARUTBASE1},
188 {IDT_SW_NTP12_BARSETUP2, IDT_SW_NTP12_BARLIMIT2,
189 IDT_SW_NTP12_BARLTBASE2, IDT_SW_NTP12_BARUTBASE2},
190 {IDT_SW_NTP12_BARSETUP3, IDT_SW_NTP12_BARLIMIT3,
191 IDT_SW_NTP12_BARLTBASE3, IDT_SW_NTP12_BARUTBASE3},
192 {IDT_SW_NTP12_BARSETUP4, IDT_SW_NTP12_BARLIMIT4,
193 IDT_SW_NTP12_BARLTBASE4, IDT_SW_NTP12_BARUTBASE4},
194 {IDT_SW_NTP12_BARSETUP5, IDT_SW_NTP12_BARLIMIT5,
195 IDT_SW_NTP12_BARLTBASE5, IDT_SW_NTP12_BARUTBASE5} } },
196 {0},
197 {0},
198 {0},
199 { IDT_SW_NTP16_PCIECMDSTS, IDT_SW_NTP16_PCIELCTLSTS,
200 IDT_SW_NTP16_NTCTL,
201 IDT_SW_SWPORT16CTL, IDT_SW_SWPORT16STS,
202 { {IDT_SW_NTP16_BARSETUP0, IDT_SW_NTP16_BARLIMIT0,
203 IDT_SW_NTP16_BARLTBASE0, IDT_SW_NTP16_BARUTBASE0},
204 {IDT_SW_NTP16_BARSETUP1, IDT_SW_NTP16_BARLIMIT1,
205 IDT_SW_NTP16_BARLTBASE1, IDT_SW_NTP16_BARUTBASE1},
206 {IDT_SW_NTP16_BARSETUP2, IDT_SW_NTP16_BARLIMIT2,
207 IDT_SW_NTP16_BARLTBASE2, IDT_SW_NTP16_BARUTBASE2},
208 {IDT_SW_NTP16_BARSETUP3, IDT_SW_NTP16_BARLIMIT3,
209 IDT_SW_NTP16_BARLTBASE3, IDT_SW_NTP16_BARUTBASE3},
210 {IDT_SW_NTP16_BARSETUP4, IDT_SW_NTP16_BARLIMIT4,
211 IDT_SW_NTP16_BARLTBASE4, IDT_SW_NTP16_BARUTBASE4},
212 {IDT_SW_NTP16_BARSETUP5, IDT_SW_NTP16_BARLIMIT5,
213 IDT_SW_NTP16_BARLTBASE5, IDT_SW_NTP16_BARUTBASE5} } },
214 {0},
215 {0},
216 {0},
217 { IDT_SW_NTP20_PCIECMDSTS, IDT_SW_NTP20_PCIELCTLSTS,
218 IDT_SW_NTP20_NTCTL,
219 IDT_SW_SWPORT20CTL, IDT_SW_SWPORT20STS,
220 { {IDT_SW_NTP20_BARSETUP0, IDT_SW_NTP20_BARLIMIT0,
221 IDT_SW_NTP20_BARLTBASE0, IDT_SW_NTP20_BARUTBASE0},
222 {IDT_SW_NTP20_BARSETUP1, IDT_SW_NTP20_BARLIMIT1,
223 IDT_SW_NTP20_BARLTBASE1, IDT_SW_NTP20_BARUTBASE1},
224 {IDT_SW_NTP20_BARSETUP2, IDT_SW_NTP20_BARLIMIT2,
225 IDT_SW_NTP20_BARLTBASE2, IDT_SW_NTP20_BARUTBASE2},
226 {IDT_SW_NTP20_BARSETUP3, IDT_SW_NTP20_BARLIMIT3,
227 IDT_SW_NTP20_BARLTBASE3, IDT_SW_NTP20_BARUTBASE3},
228 {IDT_SW_NTP20_BARSETUP4, IDT_SW_NTP20_BARLIMIT4,
229 IDT_SW_NTP20_BARLTBASE4, IDT_SW_NTP20_BARUTBASE4},
230 {IDT_SW_NTP20_BARSETUP5, IDT_SW_NTP20_BARLIMIT5,
231 IDT_SW_NTP20_BARLTBASE5, IDT_SW_NTP20_BARUTBASE5} } },
232 {0},
233 {0},
234 {0}
235};
236
237
238
239
240
241static const struct idt_ntb_part partdata_tbl[IDT_MAX_NR_PARTS] = {
242 { IDT_SW_SWPART0CTL, IDT_SW_SWPART0STS,
243 {IDT_SW_SWP0MSGCTL0, IDT_SW_SWP0MSGCTL1,
244 IDT_SW_SWP0MSGCTL2, IDT_SW_SWP0MSGCTL3} },
245 { IDT_SW_SWPART1CTL, IDT_SW_SWPART1STS,
246 {IDT_SW_SWP1MSGCTL0, IDT_SW_SWP1MSGCTL1,
247 IDT_SW_SWP1MSGCTL2, IDT_SW_SWP1MSGCTL3} },
248 { IDT_SW_SWPART2CTL, IDT_SW_SWPART2STS,
249 {IDT_SW_SWP2MSGCTL0, IDT_SW_SWP2MSGCTL1,
250 IDT_SW_SWP2MSGCTL2, IDT_SW_SWP2MSGCTL3} },
251 { IDT_SW_SWPART3CTL, IDT_SW_SWPART3STS,
252 {IDT_SW_SWP3MSGCTL0, IDT_SW_SWP3MSGCTL1,
253 IDT_SW_SWP3MSGCTL2, IDT_SW_SWP3MSGCTL3} },
254 { IDT_SW_SWPART4CTL, IDT_SW_SWPART4STS,
255 {IDT_SW_SWP4MSGCTL0, IDT_SW_SWP4MSGCTL1,
256 IDT_SW_SWP4MSGCTL2, IDT_SW_SWP4MSGCTL3} },
257 { IDT_SW_SWPART5CTL, IDT_SW_SWPART5STS,
258 {IDT_SW_SWP5MSGCTL0, IDT_SW_SWP5MSGCTL1,
259 IDT_SW_SWP5MSGCTL2, IDT_SW_SWP5MSGCTL3} },
260 { IDT_SW_SWPART6CTL, IDT_SW_SWPART6STS,
261 {IDT_SW_SWP6MSGCTL0, IDT_SW_SWP6MSGCTL1,
262 IDT_SW_SWP6MSGCTL2, IDT_SW_SWP6MSGCTL3} },
263 { IDT_SW_SWPART7CTL, IDT_SW_SWPART7STS,
264 {IDT_SW_SWP7MSGCTL0, IDT_SW_SWP7MSGCTL1,
265 IDT_SW_SWP7MSGCTL2, IDT_SW_SWP7MSGCTL3} }
266};
267
268
269
270
271static struct dentry *dbgfs_topdir;
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296static void idt_nt_write(struct idt_ntb_dev *ndev,
297 const unsigned int reg, const u32 data)
298{
299
300
301
302
303 if (WARN_ON(reg > IDT_REG_PCI_MAX || !IS_ALIGNED(reg, IDT_REG_ALIGN)))
304 return;
305
306
307 iowrite32(data, ndev->cfgspc + (ptrdiff_t)reg);
308}
309
310
311
312
313
314
315
316
317
318
319static u32 idt_nt_read(struct idt_ntb_dev *ndev, const unsigned int reg)
320{
321
322
323
324
325 if (WARN_ON(reg > IDT_REG_PCI_MAX || !IS_ALIGNED(reg, IDT_REG_ALIGN)))
326 return ~0;
327
328
329 return ioread32(ndev->cfgspc + (ptrdiff_t)reg);
330}
331
332
333
334
335
336
337
338
339
340static void idt_sw_write(struct idt_ntb_dev *ndev,
341 const unsigned int reg, const u32 data)
342{
343 unsigned long irqflags;
344
345
346
347
348
349 if (WARN_ON(reg > IDT_REG_SW_MAX || !IS_ALIGNED(reg, IDT_REG_ALIGN)))
350 return;
351
352
353 spin_lock_irqsave(&ndev->gasa_lock, irqflags);
354
355 iowrite32((u32)reg, ndev->cfgspc + (ptrdiff_t)IDT_NT_GASAADDR);
356
357 iowrite32(data, ndev->cfgspc + (ptrdiff_t)IDT_NT_GASADATA);
358
359 mmiowb();
360
361 spin_unlock_irqrestore(&ndev->gasa_lock, irqflags);
362}
363
364
365
366
367
368
369
370
371
372
373static u32 idt_sw_read(struct idt_ntb_dev *ndev, const unsigned int reg)
374{
375 unsigned long irqflags;
376 u32 data;
377
378
379
380
381
382 if (WARN_ON(reg > IDT_REG_SW_MAX || !IS_ALIGNED(reg, IDT_REG_ALIGN)))
383 return ~0;
384
385
386 spin_lock_irqsave(&ndev->gasa_lock, irqflags);
387
388 iowrite32((u32)reg, ndev->cfgspc + (ptrdiff_t)IDT_NT_GASAADDR);
389
390 data = ioread32(ndev->cfgspc + (ptrdiff_t)IDT_NT_GASADATA);
391
392 spin_unlock_irqrestore(&ndev->gasa_lock, irqflags);
393
394 return data;
395}
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413static inline int idt_reg_set_bits(struct idt_ntb_dev *ndev, unsigned int reg,
414 spinlock_t *reg_lock,
415 u64 valid_mask, u64 set_bits)
416{
417 unsigned long irqflags;
418 u32 data;
419
420 if (set_bits & ~(u64)valid_mask)
421 return -EINVAL;
422
423
424 spin_lock_irqsave(reg_lock, irqflags);
425 data = idt_nt_read(ndev, reg) | (u32)set_bits;
426 idt_nt_write(ndev, reg, data);
427
428 spin_unlock_irqrestore(reg_lock, irqflags);
429
430 return 0;
431}
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449static inline void idt_reg_clear_bits(struct idt_ntb_dev *ndev,
450 unsigned int reg, spinlock_t *reg_lock,
451 u64 clear_bits)
452{
453 unsigned long irqflags;
454 u32 data;
455
456
457 spin_lock_irqsave(reg_lock, irqflags);
458 data = idt_nt_read(ndev, reg) & ~(u32)clear_bits;
459 idt_nt_write(ndev, reg, data);
460
461 spin_unlock_irqrestore(reg_lock, irqflags);
462}
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479static int idt_scan_ports(struct idt_ntb_dev *ndev)
480{
481 unsigned char pidx, port, part;
482 u32 data, portsts, partsts;
483
484
485 data = idt_nt_read(ndev, IDT_NT_PCIELCAP);
486 ndev->port = GET_FIELD(PCIELCAP_PORTNUM, data);
487
488
489 portsts = idt_sw_read(ndev, portdata_tbl[ndev->port].sts);
490 ndev->part = GET_FIELD(SWPORTxSTS_SWPART, portsts);
491
492
493 memset(ndev->port_idx_map, -EINVAL, sizeof(ndev->port_idx_map));
494 memset(ndev->part_idx_map, -EINVAL, sizeof(ndev->part_idx_map));
495
496
497
498
499
500 ndev->peer_cnt = 0;
501 for (pidx = 0; pidx < ndev->swcfg->port_cnt; pidx++) {
502 port = ndev->swcfg->ports[pidx];
503
504 if (port == ndev->port)
505 continue;
506
507
508 portsts = idt_sw_read(ndev, portdata_tbl[port].sts);
509 part = GET_FIELD(SWPORTxSTS_SWPART, portsts);
510
511
512 partsts = idt_sw_read(ndev, partdata_tbl[part].sts);
513
514 if (IS_FLD_SET(SWPARTxSTS_STATE, partsts, ACT) &&
515 (IS_FLD_SET(SWPORTxSTS_MODE, portsts, NT) ||
516 IS_FLD_SET(SWPORTxSTS_MODE, portsts, USNT) ||
517 IS_FLD_SET(SWPORTxSTS_MODE, portsts, USNTDMA) ||
518 IS_FLD_SET(SWPORTxSTS_MODE, portsts, NTDMA))) {
519
520 ndev->peers[ndev->peer_cnt].port = port;
521 ndev->peers[ndev->peer_cnt].part = part;
522
523 ndev->port_idx_map[port] = ndev->peer_cnt;
524 ndev->part_idx_map[part] = ndev->peer_cnt;
525 ndev->peer_cnt++;
526 }
527 }
528
529 dev_dbg(&ndev->ntb.pdev->dev, "Local port: %hhu, num of peers: %hhu\n",
530 ndev->port, ndev->peer_cnt);
531
532
533 if (ndev->peer_cnt == 0) {
534 dev_warn(&ndev->ntb.pdev->dev, "No active peer found\n");
535 return -ENODEV;
536 }
537
538 return 0;
539}
540
541
542
543
544
545
546
547static int idt_ntb_port_number(struct ntb_dev *ntb)
548{
549 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
550
551 return ndev->port;
552}
553
554
555
556
557
558
559
560
561
562static int idt_ntb_peer_port_count(struct ntb_dev *ntb)
563{
564 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
565
566 return ndev->peer_cnt;
567}
568
569
570
571
572
573
574
575
576static int idt_ntb_peer_port_number(struct ntb_dev *ntb, int pidx)
577{
578 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
579
580 if (pidx < 0 || ndev->peer_cnt <= pidx)
581 return -EINVAL;
582
583
584 return ndev->peers[pidx].port;
585}
586
587
588
589
590
591
592
593
594
595
596
597static int idt_ntb_peer_port_idx(struct ntb_dev *ntb, int port)
598{
599 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
600
601 if (port < 0 || IDT_MAX_NR_PORTS <= port)
602 return -EINVAL;
603
604 return ndev->port_idx_map[port];
605}
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620static void idt_ntb_local_link_disable(struct idt_ntb_dev *ndev);
621
622
623
624
625
626
627
628
629
630
631
632
633
634static void idt_init_link(struct idt_ntb_dev *ndev)
635{
636 u32 part_mask, port_mask, se_mask;
637 unsigned char pidx;
638
639
640 spin_lock_init(&ndev->mtbl_lock);
641
642
643 port_mask = ~BIT(ndev->port);
644 part_mask = ~BIT(ndev->part);
645 for (pidx = 0; pidx < ndev->peer_cnt; pidx++) {
646 port_mask &= ~BIT(ndev->peers[pidx].port);
647 part_mask &= ~BIT(ndev->peers[pidx].part);
648 }
649
650
651 idt_sw_write(ndev, IDT_SW_SELINKUPSTS, (u32)-1);
652 idt_sw_write(ndev, IDT_SW_SELINKDNSTS, (u32)-1);
653 idt_sw_write(ndev, IDT_SW_SEGSIGSTS, (u32)-1);
654
655
656 idt_sw_write(ndev, IDT_SW_SEPMSK, part_mask);
657
658
659 idt_sw_write(ndev, IDT_SW_SELINKUPMSK, port_mask);
660
661
662 idt_sw_write(ndev, IDT_SW_SELINKDNMSK, port_mask);
663
664
665 idt_sw_write(ndev, IDT_SW_SEGSIGMSK, part_mask);
666
667
668 se_mask = ~(IDT_SEMSK_LINKUP | IDT_SEMSK_LINKDN | IDT_SEMSK_GSIGNAL);
669 idt_sw_write(ndev, IDT_SW_SEMSK, se_mask);
670
671 dev_dbg(&ndev->ntb.pdev->dev, "NTB link status events initialized");
672}
673
674
675
676
677
678
679
680static void idt_deinit_link(struct idt_ntb_dev *ndev)
681{
682
683 idt_ntb_local_link_disable(ndev);
684
685 dev_dbg(&ndev->ntb.pdev->dev, "NTB link status events deinitialized");
686}
687
688
689
690
691
692
693
694
695
696
697
698static void idt_se_isr(struct idt_ntb_dev *ndev, u32 ntint_sts)
699{
700 u32 sests;
701
702
703 sests = idt_sw_read(ndev, IDT_SW_SESTS);
704
705
706 idt_sw_write(ndev, IDT_SW_SELINKUPSTS, (u32)-1);
707 idt_sw_write(ndev, IDT_SW_SELINKDNSTS, (u32)-1);
708 idt_sw_write(ndev, IDT_SW_SEGSIGSTS, (u32)-1);
709
710
711 idt_nt_write(ndev, IDT_NT_NTINTSTS, IDT_NTINTSTS_SEVENT);
712
713 dev_dbg(&ndev->ntb.pdev->dev, "SE IRQ detected %#08x (SESTS %#08x)",
714 ntint_sts, sests);
715
716
717 ntb_link_event(&ndev->ntb);
718}
719
720
721
722
723
724
725
726
727
728
729static void idt_ntb_local_link_enable(struct idt_ntb_dev *ndev)
730{
731 u32 reqid, mtbldata = 0;
732 unsigned long irqflags;
733
734
735 idt_nt_write(ndev, IDT_NT_NTCTL, IDT_NTCTL_CPEN);
736
737
738 reqid = idt_nt_read(ndev, IDT_NT_REQIDCAP);
739
740
741
742
743
744 mtbldata = SET_FIELD(NTMTBLDATA_REQID, 0, reqid) |
745 SET_FIELD(NTMTBLDATA_PART, 0, ndev->part) |
746 IDT_NTMTBLDATA_VALID;
747 spin_lock_irqsave(&ndev->mtbl_lock, irqflags);
748 idt_nt_write(ndev, IDT_NT_NTMTBLADDR, ndev->part);
749 idt_nt_write(ndev, IDT_NT_NTMTBLDATA, mtbldata);
750 mmiowb();
751 spin_unlock_irqrestore(&ndev->mtbl_lock, irqflags);
752
753
754 idt_nt_write(ndev, IDT_NT_NTGSIGNAL, IDT_NTGSIGNAL_SET);
755 idt_sw_write(ndev, IDT_SW_SEGSIGSTS, (u32)1 << ndev->part);
756}
757
758
759
760
761
762
763
764
765
766
767static void idt_ntb_local_link_disable(struct idt_ntb_dev *ndev)
768{
769 unsigned long irqflags;
770
771
772 idt_nt_write(ndev, IDT_NT_NTCTL, 0);
773
774
775 spin_lock_irqsave(&ndev->mtbl_lock, irqflags);
776 idt_nt_write(ndev, IDT_NT_NTMTBLADDR, ndev->part);
777 idt_nt_write(ndev, IDT_NT_NTMTBLDATA, 0);
778 mmiowb();
779 spin_unlock_irqrestore(&ndev->mtbl_lock, irqflags);
780
781
782 idt_nt_write(ndev, IDT_NT_NTGSIGNAL, IDT_NTGSIGNAL_SET);
783 idt_sw_write(ndev, IDT_SW_SEGSIGSTS, (u32)1 << ndev->part);
784}
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799static bool idt_ntb_local_link_is_up(struct idt_ntb_dev *ndev)
800{
801 unsigned long irqflags;
802 u32 data;
803
804
805 data = idt_nt_read(ndev, IDT_NT_PCICMDSTS);
806 if (!(data & IDT_PCICMDSTS_BME))
807 return false;
808
809
810 data = idt_nt_read(ndev, IDT_NT_NTCTL);
811 if (!(data & IDT_NTCTL_CPEN))
812 return false;
813
814
815 spin_lock_irqsave(&ndev->mtbl_lock, irqflags);
816 idt_nt_write(ndev, IDT_NT_NTMTBLADDR, ndev->part);
817 data = idt_nt_read(ndev, IDT_NT_NTMTBLDATA);
818 spin_unlock_irqrestore(&ndev->mtbl_lock, irqflags);
819
820 return !!(data & IDT_NTMTBLDATA_VALID);
821}
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836static bool idt_ntb_peer_link_is_up(struct idt_ntb_dev *ndev, int pidx)
837{
838 unsigned long irqflags;
839 unsigned char port;
840 u32 data;
841
842
843 port = ndev->peers[pidx].port;
844
845
846 data = idt_sw_read(ndev, portdata_tbl[port].sts);
847 if (!(data & IDT_SWPORTxSTS_LINKUP))
848 return false;
849
850
851 data = idt_sw_read(ndev, portdata_tbl[port].pcicmdsts);
852 if (!(data & IDT_PCICMDSTS_BME))
853 return false;
854
855
856 data = idt_sw_read(ndev, portdata_tbl[port].ntctl);
857 if (!(data & IDT_NTCTL_CPEN))
858 return false;
859
860
861 spin_lock_irqsave(&ndev->mtbl_lock, irqflags);
862 idt_nt_write(ndev, IDT_NT_NTMTBLADDR, ndev->peers[pidx].part);
863 data = idt_nt_read(ndev, IDT_NT_NTMTBLDATA);
864 spin_unlock_irqrestore(&ndev->mtbl_lock, irqflags);
865
866 return !!(data & IDT_NTMTBLDATA_VALID);
867}
868
869
870
871
872
873
874
875
876
877
878
879
880static u64 idt_ntb_link_is_up(struct ntb_dev *ntb,
881 enum ntb_speed *speed, enum ntb_width *width)
882{
883 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
884 unsigned char pidx;
885 u64 status;
886 u32 data;
887
888
889 if (speed != NULL || width != NULL) {
890 data = idt_nt_read(ndev, IDT_NT_PCIELCTLSTS);
891 if (speed != NULL)
892 *speed = GET_FIELD(PCIELCTLSTS_CLS, data);
893 if (width != NULL)
894 *width = GET_FIELD(PCIELCTLSTS_NLW, data);
895 }
896
897
898 if (!idt_ntb_local_link_is_up(ndev))
899 return 0;
900
901
902 status = 0;
903 for (pidx = 0; pidx < ndev->peer_cnt; pidx++) {
904 if (idt_ntb_peer_link_is_up(ndev, pidx))
905 status |= ((u64)1 << pidx);
906 }
907
908 return status;
909}
910
911
912
913
914
915
916
917
918
919
920
921static int idt_ntb_link_enable(struct ntb_dev *ntb, enum ntb_speed speed,
922 enum ntb_width width)
923{
924 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
925
926
927 idt_ntb_local_link_enable(ndev);
928
929 dev_dbg(&ndev->ntb.pdev->dev, "Local NTB link enabled");
930
931 return 0;
932}
933
934
935
936
937
938
939
940
941
942static int idt_ntb_link_disable(struct ntb_dev *ntb)
943{
944 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
945
946
947 idt_ntb_local_link_disable(ndev);
948
949 dev_dbg(&ndev->ntb.pdev->dev, "Local NTB link disabled");
950
951 return 0;
952}
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993static inline unsigned char idt_get_mw_count(enum idt_mw_type mw_type)
994{
995 switch (mw_type) {
996 case IDT_MW_DIR:
997 return 1;
998 case IDT_MW_LUT12:
999 return 12;
1000 case IDT_MW_LUT24:
1001 return 24;
1002 default:
1003 break;
1004 }
1005
1006 return 0;
1007}
1008
1009
1010
1011
1012
1013
1014
1015static inline char *idt_get_mw_name(enum idt_mw_type mw_type)
1016{
1017 switch (mw_type) {
1018 case IDT_MW_DIR:
1019 return "DIR ";
1020 case IDT_MW_LUT12:
1021 return "LUT12";
1022 case IDT_MW_LUT24:
1023 return "LUT24";
1024 default:
1025 break;
1026 }
1027
1028 return "unknown";
1029}
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042static struct idt_mw_cfg *idt_scan_mws(struct idt_ntb_dev *ndev, int port,
1043 unsigned char *mw_cnt)
1044{
1045 struct idt_mw_cfg mws[IDT_MAX_NR_MWS], *ret_mws;
1046 const struct idt_ntb_bar *bars;
1047 enum idt_mw_type mw_type;
1048 unsigned char widx, bidx, en_cnt;
1049 bool bar_64bit = false;
1050 int aprt_size;
1051 u32 data;
1052
1053
1054 bars = portdata_tbl[port].bars;
1055
1056
1057 *mw_cnt = 0;
1058 for (bidx = 0; bidx < IDT_BAR_CNT; bidx += 1 + bar_64bit) {
1059
1060 data = idt_sw_read(ndev, bars[bidx].setup);
1061
1062
1063 if (!(data & IDT_BARSETUP_EN)) {
1064 bar_64bit = false;
1065 continue;
1066 }
1067
1068
1069 bar_64bit = IS_FLD_SET(BARSETUP_TYPE, data, 64);
1070
1071
1072 if (data & IDT_BARSETUP_MODE_CFG)
1073 continue;
1074
1075
1076 mw_type = GET_FIELD(BARSETUP_ATRAN, data);
1077 en_cnt = idt_get_mw_count(mw_type);
1078 aprt_size = (u64)1 << GET_FIELD(BARSETUP_SIZE, data);
1079
1080
1081 for (widx = 0; widx < en_cnt; widx++, (*mw_cnt)++) {
1082
1083
1084
1085
1086 if (*mw_cnt >= IDT_MAX_NR_MWS)
1087 return ERR_PTR(-EINVAL);
1088
1089
1090 mws[*mw_cnt].type = mw_type;
1091 mws[*mw_cnt].bar = bidx;
1092 mws[*mw_cnt].idx = widx;
1093
1094 mws[*mw_cnt].addr_align = IDT_TRANS_ALIGN;
1095
1096 if (mw_type == IDT_MW_DIR)
1097 mws[*mw_cnt].size_max = aprt_size;
1098 else if (mw_type == IDT_MW_LUT12)
1099 mws[*mw_cnt].size_max = aprt_size / 16;
1100 else
1101 mws[*mw_cnt].size_max = aprt_size / 32;
1102 mws[*mw_cnt].size_align = (mw_type == IDT_MW_DIR) ?
1103 IDT_DIR_SIZE_ALIGN : mws[*mw_cnt].size_max;
1104 }
1105 }
1106
1107
1108 ret_mws = devm_kcalloc(&ndev->ntb.pdev->dev, *mw_cnt,
1109 sizeof(*ret_mws), GFP_KERNEL);
1110 if (IS_ERR_OR_NULL(ret_mws))
1111 return ERR_PTR(-ENOMEM);
1112
1113
1114 memcpy(ret_mws, mws, (*mw_cnt)*sizeof(*ret_mws));
1115
1116 return ret_mws;
1117}
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128static int idt_init_mws(struct idt_ntb_dev *ndev)
1129{
1130 struct idt_ntb_peer *peer;
1131 unsigned char pidx;
1132
1133
1134 ndev->mws = idt_scan_mws(ndev, ndev->port, &ndev->mw_cnt);
1135 if (IS_ERR(ndev->mws)) {
1136 dev_err(&ndev->ntb.pdev->dev,
1137 "Failed to scan mws of local port %hhu", ndev->port);
1138 return PTR_ERR(ndev->mws);
1139 }
1140
1141
1142 for (pidx = 0; pidx < ndev->peer_cnt; pidx++) {
1143 peer = &ndev->peers[pidx];
1144 peer->mws = idt_scan_mws(ndev, peer->port, &peer->mw_cnt);
1145 if (IS_ERR(peer->mws)) {
1146 dev_err(&ndev->ntb.pdev->dev,
1147 "Failed to scan mws of port %hhu", peer->port);
1148 return PTR_ERR(peer->mws);
1149 }
1150 }
1151
1152
1153 spin_lock_init(&ndev->lut_lock);
1154
1155 dev_dbg(&ndev->ntb.pdev->dev, "Outbound and inbound MWs initialized");
1156
1157 return 0;
1158}
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171static int idt_ntb_mw_count(struct ntb_dev *ntb, int pidx)
1172{
1173 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
1174
1175 if (pidx < 0 || ndev->peer_cnt <= pidx)
1176 return -EINVAL;
1177
1178 return ndev->peers[pidx].mw_cnt;
1179}
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195static int idt_ntb_mw_get_align(struct ntb_dev *ntb, int pidx, int widx,
1196 resource_size_t *addr_align,
1197 resource_size_t *size_align,
1198 resource_size_t *size_max)
1199{
1200 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
1201 struct idt_ntb_peer *peer;
1202
1203 if (pidx < 0 || ndev->peer_cnt <= pidx)
1204 return -EINVAL;
1205
1206 peer = &ndev->peers[pidx];
1207
1208 if (widx < 0 || peer->mw_cnt <= widx)
1209 return -EINVAL;
1210
1211 if (addr_align != NULL)
1212 *addr_align = peer->mws[widx].addr_align;
1213
1214 if (size_align != NULL)
1215 *size_align = peer->mws[widx].size_align;
1216
1217 if (size_max != NULL)
1218 *size_max = peer->mws[widx].size_max;
1219
1220 return 0;
1221}
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233static int idt_ntb_peer_mw_count(struct ntb_dev *ntb)
1234{
1235 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
1236
1237 return ndev->mw_cnt;
1238}
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253static int idt_ntb_peer_mw_get_addr(struct ntb_dev *ntb, int widx,
1254 phys_addr_t *base, resource_size_t *size)
1255{
1256 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
1257
1258 if (widx < 0 || ndev->mw_cnt <= widx)
1259 return -EINVAL;
1260
1261
1262 if (base != NULL)
1263 *base = pci_resource_start(ntb->pdev, ndev->mws[widx].bar) +
1264 ndev->mws[widx].idx * ndev->mws[widx].size_max;
1265
1266
1267 if (size != NULL)
1268 *size = ndev->mws[widx].size_max;
1269
1270 return 0;
1271}
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288static int idt_ntb_peer_mw_set_trans(struct ntb_dev *ntb, int pidx, int widx,
1289 u64 addr, resource_size_t size)
1290{
1291 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
1292 struct idt_mw_cfg *mw_cfg;
1293 u32 data = 0, lutoff = 0;
1294
1295 if (pidx < 0 || ndev->peer_cnt <= pidx)
1296 return -EINVAL;
1297
1298 if (widx < 0 || ndev->mw_cnt <= widx)
1299 return -EINVAL;
1300
1301
1302
1303
1304
1305 mw_cfg = &ndev->mws[widx];
1306 if (!IS_ALIGNED(addr, mw_cfg->addr_align))
1307 return -EINVAL;
1308 if (!IS_ALIGNED(size, mw_cfg->size_align) || size > mw_cfg->size_max)
1309 return -EINVAL;
1310
1311
1312 if (mw_cfg->type == IDT_MW_DIR) {
1313 const struct idt_ntb_bar *bar = &ntdata_tbl.bars[mw_cfg->bar];
1314 u64 limit;
1315
1316 data = idt_nt_read(ndev, bar->setup);
1317 data = SET_FIELD(BARSETUP_TPART, data, ndev->peers[pidx].part);
1318 idt_nt_write(ndev, bar->setup, data);
1319
1320 idt_nt_write(ndev, bar->ltbase, (u32)addr);
1321 idt_nt_write(ndev, bar->utbase, (u32)(addr >> 32));
1322
1323 limit = pci_resource_start(ntb->pdev, mw_cfg->bar) + size;
1324 idt_nt_write(ndev, bar->limit, (u32)limit);
1325 if (IS_FLD_SET(BARSETUP_TYPE, data, 64))
1326 idt_nt_write(ndev, (bar + 1)->limit, (limit >> 32));
1327 } else {
1328 unsigned long irqflags;
1329
1330 lutoff = SET_FIELD(LUTOFFSET_INDEX, 0, mw_cfg->idx) |
1331 SET_FIELD(LUTOFFSET_BAR, 0, mw_cfg->bar);
1332 data = SET_FIELD(LUTUDATA_PART, 0, ndev->peers[pidx].part) |
1333 IDT_LUTUDATA_VALID;
1334 spin_lock_irqsave(&ndev->lut_lock, irqflags);
1335 idt_nt_write(ndev, IDT_NT_LUTOFFSET, lutoff);
1336 idt_nt_write(ndev, IDT_NT_LUTLDATA, (u32)addr);
1337 idt_nt_write(ndev, IDT_NT_LUTMDATA, (u32)(addr >> 32));
1338 idt_nt_write(ndev, IDT_NT_LUTUDATA, data);
1339 mmiowb();
1340 spin_unlock_irqrestore(&ndev->lut_lock, irqflags);
1341
1342 }
1343
1344 return 0;
1345}
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358static int idt_ntb_peer_mw_clear_trans(struct ntb_dev *ntb, int pidx,
1359 int widx)
1360{
1361 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
1362 struct idt_mw_cfg *mw_cfg;
1363
1364 if (pidx < 0 || ndev->peer_cnt <= pidx)
1365 return -EINVAL;
1366
1367 if (widx < 0 || ndev->mw_cnt <= widx)
1368 return -EINVAL;
1369
1370 mw_cfg = &ndev->mws[widx];
1371
1372
1373 if (mw_cfg->type == IDT_MW_DIR) {
1374 const struct idt_ntb_bar *bar = &ntdata_tbl.bars[mw_cfg->bar];
1375 u32 data;
1376
1377 data = idt_nt_read(ndev, bar->setup);
1378
1379 idt_nt_write(ndev, bar->limit, 0);
1380 if (IS_FLD_SET(BARSETUP_TYPE, data, 64))
1381 idt_nt_write(ndev, (bar + 1)->limit, 0);
1382 } else {
1383 unsigned long irqflags;
1384 u32 lutoff;
1385
1386 lutoff = SET_FIELD(LUTOFFSET_INDEX, 0, mw_cfg->idx) |
1387 SET_FIELD(LUTOFFSET_BAR, 0, mw_cfg->bar);
1388 spin_lock_irqsave(&ndev->lut_lock, irqflags);
1389 idt_nt_write(ndev, IDT_NT_LUTOFFSET, lutoff);
1390 idt_nt_write(ndev, IDT_NT_LUTLDATA, 0);
1391 idt_nt_write(ndev, IDT_NT_LUTMDATA, 0);
1392 idt_nt_write(ndev, IDT_NT_LUTUDATA, 0);
1393 mmiowb();
1394 spin_unlock_irqrestore(&ndev->lut_lock, irqflags);
1395 }
1396
1397 return 0;
1398}
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429static void idt_db_isr(struct idt_ntb_dev *ndev, u32 ntint_sts)
1430{
1431
1432
1433
1434
1435 dev_dbg(&ndev->ntb.pdev->dev, "DB IRQ detected %#08x", ntint_sts);
1436
1437
1438 ntb_db_event(&ndev->ntb, 0);
1439}
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450static u64 idt_ntb_db_valid_mask(struct ntb_dev *ntb)
1451{
1452 return IDT_DBELL_MASK;
1453}
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464static u64 idt_ntb_db_read(struct ntb_dev *ntb)
1465{
1466 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
1467
1468 return idt_nt_read(ndev, IDT_NT_INDBELLSTS);
1469}
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484static int idt_ntb_db_clear(struct ntb_dev *ntb, u64 db_bits)
1485{
1486 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
1487
1488 idt_nt_write(ndev, IDT_NT_INDBELLSTS, (u32)db_bits);
1489
1490 return 0;
1491}
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503static u64 idt_ntb_db_read_mask(struct ntb_dev *ntb)
1504{
1505 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
1506
1507 return idt_nt_read(ndev, IDT_NT_INDBELLMSK);
1508}
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521static int idt_ntb_db_set_mask(struct ntb_dev *ntb, u64 db_bits)
1522{
1523 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
1524
1525 return idt_reg_set_bits(ndev, IDT_NT_INDBELLMSK, &ndev->db_mask_lock,
1526 IDT_DBELL_MASK, db_bits);
1527}
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542static int idt_ntb_db_clear_mask(struct ntb_dev *ntb, u64 db_bits)
1543{
1544 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
1545
1546 idt_reg_clear_bits(ndev, IDT_NT_INDBELLMSK, &ndev->db_mask_lock,
1547 db_bits);
1548
1549 return 0;
1550}
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563static int idt_ntb_peer_db_set(struct ntb_dev *ntb, u64 db_bits)
1564{
1565 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
1566
1567 if (db_bits & ~(u64)IDT_DBELL_MASK)
1568 return -EINVAL;
1569
1570 idt_nt_write(ndev, IDT_NT_OUTDBELLSET, (u32)db_bits);
1571 return 0;
1572}
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591static void idt_init_msg(struct idt_ntb_dev *ndev)
1592{
1593 unsigned char midx;
1594
1595
1596 for (midx = 0; midx < IDT_MSG_CNT; midx++)
1597 spin_lock_init(&ndev->msg_locks[midx]);
1598
1599 dev_dbg(&ndev->ntb.pdev->dev, "NTB Messaging initialized");
1600}
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612static void idt_msg_isr(struct idt_ntb_dev *ndev, u32 ntint_sts)
1613{
1614
1615
1616
1617
1618 dev_dbg(&ndev->ntb.pdev->dev, "Message IRQ detected %#08x", ntint_sts);
1619
1620
1621 ntb_msg_event(&ndev->ntb);
1622}
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632static int idt_ntb_msg_count(struct ntb_dev *ntb)
1633{
1634 return IDT_MSG_CNT;
1635}
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647static u64 idt_ntb_msg_inbits(struct ntb_dev *ntb)
1648{
1649 return (u64)IDT_INMSG_MASK;
1650}
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662static u64 idt_ntb_msg_outbits(struct ntb_dev *ntb)
1663{
1664 return (u64)IDT_OUTMSG_MASK;
1665}
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676static u64 idt_ntb_msg_read_sts(struct ntb_dev *ntb)
1677{
1678 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
1679
1680 return idt_nt_read(ndev, IDT_NT_MSGSTS);
1681}
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696static int idt_ntb_msg_clear_sts(struct ntb_dev *ntb, u64 sts_bits)
1697{
1698 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
1699
1700 idt_nt_write(ndev, IDT_NT_MSGSTS, sts_bits);
1701
1702 return 0;
1703}
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715static int idt_ntb_msg_set_mask(struct ntb_dev *ntb, u64 mask_bits)
1716{
1717 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
1718
1719 return idt_reg_set_bits(ndev, IDT_NT_MSGSTSMSK, &ndev->msg_mask_lock,
1720 IDT_MSG_MASK, mask_bits);
1721}
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733static int idt_ntb_msg_clear_mask(struct ntb_dev *ntb, u64 mask_bits)
1734{
1735 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
1736
1737 idt_reg_clear_bits(ndev, IDT_NT_MSGSTSMSK, &ndev->msg_mask_lock,
1738 mask_bits);
1739
1740 return 0;
1741}
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754static u32 idt_ntb_msg_read(struct ntb_dev *ntb, int *pidx, int midx)
1755{
1756 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
1757
1758 if (midx < 0 || IDT_MSG_CNT <= midx)
1759 return ~(u32)0;
1760
1761
1762 if (pidx != NULL) {
1763 u32 srcpart;
1764
1765 srcpart = idt_nt_read(ndev, ntdata_tbl.msgs[midx].src);
1766 *pidx = ndev->part_idx_map[srcpart];
1767
1768
1769 if (*pidx == -EINVAL)
1770 *pidx = 0;
1771 }
1772
1773
1774 return idt_nt_read(ndev, ntdata_tbl.msgs[midx].in);
1775}
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790static int idt_ntb_peer_msg_write(struct ntb_dev *ntb, int pidx, int midx,
1791 u32 msg)
1792{
1793 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
1794 unsigned long irqflags;
1795 u32 swpmsgctl = 0;
1796
1797 if (midx < 0 || IDT_MSG_CNT <= midx)
1798 return -EINVAL;
1799
1800 if (pidx < 0 || ndev->peer_cnt <= pidx)
1801 return -EINVAL;
1802
1803
1804 swpmsgctl = SET_FIELD(SWPxMSGCTL_REG, 0, midx) |
1805 SET_FIELD(SWPxMSGCTL_PART, 0, ndev->peers[pidx].part);
1806
1807
1808 spin_lock_irqsave(&ndev->msg_locks[midx], irqflags);
1809
1810 idt_sw_write(ndev, partdata_tbl[ndev->part].msgctl[midx], swpmsgctl);
1811 idt_nt_write(ndev, ntdata_tbl.msgs[midx].out, msg);
1812 mmiowb();
1813
1814 spin_unlock_irqrestore(&ndev->msg_locks[midx], irqflags);
1815
1816
1817 return 0;
1818}
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837static void idt_read_temp(struct idt_ntb_dev *ndev, unsigned char *val,
1838 unsigned char *frac)
1839{
1840 u32 data;
1841
1842
1843 data = idt_sw_read(ndev, IDT_SW_TMPSTS);
1844 data = GET_FIELD(TMPSTS_TEMP, data);
1845
1846 *val = data >> 1;
1847 *frac = ((data & 0x1) ? 5 : 0);
1848}
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861static void idt_temp_isr(struct idt_ntb_dev *ndev, u32 ntint_sts)
1862{
1863 unsigned char val, frac;
1864
1865
1866 idt_read_temp(ndev, &val, &frac);
1867
1868
1869
1870
1871
1872 idt_nt_write(ndev, IDT_NT_NTINTSTS, IDT_NTINTSTS_TMPSENSOR);
1873
1874 dev_dbg(&ndev->ntb.pdev->dev,
1875 "Temp sensor IRQ detected %#08x", ntint_sts);
1876
1877
1878 dev_warn(&ndev->ntb.pdev->dev, "Temperature %hhu.%hhu", val, frac);
1879}
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898static irqreturn_t idt_thread_isr(int irq, void *devid);
1899
1900
1901
1902
1903
1904
1905
1906static int idt_init_isr(struct idt_ntb_dev *ndev)
1907{
1908 struct pci_dev *pdev = ndev->ntb.pdev;
1909 u32 ntint_mask;
1910 int ret;
1911
1912
1913 ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI | PCI_IRQ_LEGACY);
1914 if (ret != 1) {
1915 dev_err(&pdev->dev, "Failed to allocate IRQ vector");
1916 return ret;
1917 }
1918
1919
1920 ret = pci_irq_vector(pdev, 0);
1921 if (ret < 0) {
1922 dev_err(&pdev->dev, "Failed to get IRQ vector");
1923 goto err_free_vectors;
1924 }
1925
1926
1927 ret = devm_request_threaded_irq(&pdev->dev, ret, NULL, idt_thread_isr,
1928 IRQF_ONESHOT, NTB_IRQNAME, ndev);
1929 if (ret != 0) {
1930 dev_err(&pdev->dev, "Failed to set MSI IRQ handler, %d", ret);
1931 goto err_free_vectors;
1932 }
1933
1934
1935 ntint_mask = idt_nt_read(ndev, IDT_NT_NTINTMSK) & ~IDT_NTINTMSK_ALL;
1936 idt_nt_write(ndev, IDT_NT_NTINTMSK, ntint_mask);
1937
1938
1939 dev_dbg(&pdev->dev, "NTB interrupts initialized");
1940
1941 return 0;
1942
1943err_free_vectors:
1944 pci_free_irq_vectors(pdev);
1945
1946 return ret;
1947}
1948
1949
1950
1951
1952
1953
1954
1955
1956static void idt_deinit_isr(struct idt_ntb_dev *ndev)
1957{
1958 struct pci_dev *pdev = ndev->ntb.pdev;
1959 u32 ntint_mask;
1960
1961
1962 ntint_mask = idt_nt_read(ndev, IDT_NT_NTINTMSK) | IDT_NTINTMSK_ALL;
1963 idt_nt_write(ndev, IDT_NT_NTINTMSK, ntint_mask);
1964
1965
1966 devm_free_irq(&pdev->dev, pci_irq_vector(pdev, 0), ndev);
1967
1968
1969 pci_free_irq_vectors(pdev);
1970
1971 dev_dbg(&pdev->dev, "NTB interrupts deinitialized");
1972}
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983static irqreturn_t idt_thread_isr(int irq, void *devid)
1984{
1985 struct idt_ntb_dev *ndev = devid;
1986 bool handled = false;
1987 u32 ntint_sts;
1988
1989
1990 ntint_sts = idt_nt_read(ndev, IDT_NT_NTINTSTS);
1991
1992
1993 if (ntint_sts & IDT_NTINTSTS_MSG) {
1994 idt_msg_isr(ndev, ntint_sts);
1995 handled = true;
1996 }
1997
1998
1999 if (ntint_sts & IDT_NTINTSTS_DBELL) {
2000 idt_db_isr(ndev, ntint_sts);
2001 handled = true;
2002 }
2003
2004
2005 if (ntint_sts & IDT_NTINTSTS_SEVENT) {
2006 idt_se_isr(ndev, ntint_sts);
2007 handled = true;
2008 }
2009
2010
2011 if (ntint_sts & IDT_NTINTSTS_TMPSENSOR) {
2012 idt_temp_isr(ndev, ntint_sts);
2013 handled = true;
2014 }
2015
2016 dev_dbg(&ndev->ntb.pdev->dev, "IDT IRQs 0x%08x handled", ntint_sts);
2017
2018 return handled ? IRQ_HANDLED : IRQ_NONE;
2019}
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029static const struct ntb_dev_ops idt_ntb_ops = {
2030 .port_number = idt_ntb_port_number,
2031 .peer_port_count = idt_ntb_peer_port_count,
2032 .peer_port_number = idt_ntb_peer_port_number,
2033 .peer_port_idx = idt_ntb_peer_port_idx,
2034 .link_is_up = idt_ntb_link_is_up,
2035 .link_enable = idt_ntb_link_enable,
2036 .link_disable = idt_ntb_link_disable,
2037 .mw_count = idt_ntb_mw_count,
2038 .mw_get_align = idt_ntb_mw_get_align,
2039 .peer_mw_count = idt_ntb_peer_mw_count,
2040 .peer_mw_get_addr = idt_ntb_peer_mw_get_addr,
2041 .peer_mw_set_trans = idt_ntb_peer_mw_set_trans,
2042 .peer_mw_clear_trans = idt_ntb_peer_mw_clear_trans,
2043 .db_valid_mask = idt_ntb_db_valid_mask,
2044 .db_read = idt_ntb_db_read,
2045 .db_clear = idt_ntb_db_clear,
2046 .db_read_mask = idt_ntb_db_read_mask,
2047 .db_set_mask = idt_ntb_db_set_mask,
2048 .db_clear_mask = idt_ntb_db_clear_mask,
2049 .peer_db_set = idt_ntb_peer_db_set,
2050 .msg_count = idt_ntb_msg_count,
2051 .msg_inbits = idt_ntb_msg_inbits,
2052 .msg_outbits = idt_ntb_msg_outbits,
2053 .msg_read_sts = idt_ntb_msg_read_sts,
2054 .msg_clear_sts = idt_ntb_msg_clear_sts,
2055 .msg_set_mask = idt_ntb_msg_set_mask,
2056 .msg_clear_mask = idt_ntb_msg_clear_mask,
2057 .msg_read = idt_ntb_msg_read,
2058 .peer_msg_write = idt_ntb_peer_msg_write
2059};
2060
2061
2062
2063
2064
2065
2066
2067static int idt_register_device(struct idt_ntb_dev *ndev)
2068{
2069 int ret;
2070
2071
2072 ndev->ntb.ops = &idt_ntb_ops;
2073 ndev->ntb.topo = NTB_TOPO_SWITCH;
2074
2075 ret = ntb_register_device(&ndev->ntb);
2076 if (ret != 0) {
2077 dev_err(&ndev->ntb.pdev->dev, "Failed to register NTB device");
2078 return ret;
2079 }
2080
2081 dev_dbg(&ndev->ntb.pdev->dev, "NTB device successfully registered");
2082
2083 return 0;
2084}
2085
2086
2087
2088
2089
2090static void idt_unregister_device(struct idt_ntb_dev *ndev)
2091{
2092
2093 ntb_unregister_device(&ndev->ntb);
2094
2095 dev_dbg(&ndev->ntb.pdev->dev, "NTB device unregistered");
2096}
2097
2098
2099
2100
2101
2102
2103static ssize_t idt_dbgfs_info_read(struct file *filp, char __user *ubuf,
2104 size_t count, loff_t *offp);
2105
2106
2107
2108
2109static const struct file_operations idt_dbgfs_info_ops = {
2110 .owner = THIS_MODULE,
2111 .open = simple_open,
2112 .read = idt_dbgfs_info_read
2113};
2114
2115
2116
2117
2118
2119
2120
2121
2122static ssize_t idt_dbgfs_info_read(struct file *filp, char __user *ubuf,
2123 size_t count, loff_t *offp)
2124{
2125 struct idt_ntb_dev *ndev = filp->private_data;
2126 unsigned char temp, frac, idx, pidx, cnt;
2127 ssize_t ret = 0, off = 0;
2128 unsigned long irqflags;
2129 enum ntb_speed speed;
2130 enum ntb_width width;
2131 char *strbuf;
2132 size_t size;
2133 u32 data;
2134
2135
2136 size = min_t(size_t, count, 0x1000U);
2137
2138
2139 strbuf = kmalloc(size, GFP_KERNEL);
2140 if (strbuf == NULL)
2141 return -ENOMEM;
2142
2143
2144 off += scnprintf(strbuf + off, size - off,
2145 "\n\t\tIDT NTB device Information:\n\n");
2146
2147
2148 off += scnprintf(strbuf + off, size - off,
2149 "Local Port %hhu, Partition %hhu\n", ndev->port, ndev->part);
2150
2151
2152 off += scnprintf(strbuf + off, size - off, "Peers:\n");
2153 for (idx = 0; idx < ndev->peer_cnt; idx++) {
2154 off += scnprintf(strbuf + off, size - off,
2155 "\t%hhu. Port %hhu, Partition %hhu\n",
2156 idx, ndev->peers[idx].port, ndev->peers[idx].part);
2157 }
2158
2159
2160 data = idt_ntb_link_is_up(&ndev->ntb, &speed, &width);
2161 off += scnprintf(strbuf + off, size - off,
2162 "NTB link status\t- 0x%08x, ", data);
2163 off += scnprintf(strbuf + off, size - off, "PCIe Gen %d x%d lanes\n",
2164 speed, width);
2165
2166
2167 off += scnprintf(strbuf + off, size - off, "NTB Mapping Table:\n");
2168 for (idx = 0; idx < IDT_MTBL_ENTRY_CNT; idx++) {
2169 spin_lock_irqsave(&ndev->mtbl_lock, irqflags);
2170 idt_nt_write(ndev, IDT_NT_NTMTBLADDR, idx);
2171 data = idt_nt_read(ndev, IDT_NT_NTMTBLDATA);
2172 spin_unlock_irqrestore(&ndev->mtbl_lock, irqflags);
2173
2174
2175 if (data & IDT_NTMTBLDATA_VALID) {
2176 off += scnprintf(strbuf + off, size - off,
2177 "\t%hhu. Partition %d, Requester ID 0x%04x\n",
2178 idx, GET_FIELD(NTMTBLDATA_PART, data),
2179 GET_FIELD(NTMTBLDATA_REQID, data));
2180 }
2181 }
2182 off += scnprintf(strbuf + off, size - off, "\n");
2183
2184
2185 off += scnprintf(strbuf + off, size - off,
2186 "Outbound Memory Windows:\n");
2187 for (idx = 0; idx < ndev->mw_cnt; idx += cnt) {
2188 data = ndev->mws[idx].type;
2189 cnt = idt_get_mw_count(data);
2190
2191
2192 if (data == IDT_MW_DIR)
2193 off += scnprintf(strbuf + off, size - off,
2194 "\t%hhu.\t", idx);
2195 else
2196 off += scnprintf(strbuf + off, size - off,
2197 "\t%hhu-%hhu.\t", idx, idx + cnt - 1);
2198
2199 off += scnprintf(strbuf + off, size - off, "%s BAR%hhu, ",
2200 idt_get_mw_name(data), ndev->mws[idx].bar);
2201
2202 off += scnprintf(strbuf + off, size - off,
2203 "Address align 0x%08llx, ", ndev->mws[idx].addr_align);
2204
2205 off += scnprintf(strbuf + off, size - off,
2206 "Size align 0x%08llx, Size max %llu\n",
2207 ndev->mws[idx].size_align, ndev->mws[idx].size_max);
2208 }
2209
2210
2211 for (pidx = 0; pidx < ndev->peer_cnt; pidx++) {
2212 off += scnprintf(strbuf + off, size - off,
2213 "Inbound Memory Windows for peer %hhu (Port %hhu):\n",
2214 pidx, ndev->peers[pidx].port);
2215
2216
2217 for (idx = 0; idx < ndev->peers[pidx].mw_cnt; idx += cnt) {
2218 data = ndev->peers[pidx].mws[idx].type;
2219 cnt = idt_get_mw_count(data);
2220
2221 if (data == IDT_MW_DIR)
2222 off += scnprintf(strbuf + off, size - off,
2223 "\t%hhu.\t", idx);
2224 else
2225 off += scnprintf(strbuf + off, size - off,
2226 "\t%hhu-%hhu.\t", idx, idx + cnt - 1);
2227
2228 off += scnprintf(strbuf + off, size - off,
2229 "%s BAR%hhu, ", idt_get_mw_name(data),
2230 ndev->peers[pidx].mws[idx].bar);
2231
2232 off += scnprintf(strbuf + off, size - off,
2233 "Address align 0x%08llx, ",
2234 ndev->peers[pidx].mws[idx].addr_align);
2235
2236 off += scnprintf(strbuf + off, size - off,
2237 "Size align 0x%08llx, Size max %llu\n",
2238 ndev->peers[pidx].mws[idx].size_align,
2239 ndev->peers[pidx].mws[idx].size_max);
2240 }
2241 }
2242 off += scnprintf(strbuf + off, size - off, "\n");
2243
2244
2245 data = idt_sw_read(ndev, IDT_SW_GDBELLSTS);
2246 off += scnprintf(strbuf + off, size - off,
2247 "Global Doorbell state\t- 0x%08x\n", data);
2248 data = idt_ntb_db_read(&ndev->ntb);
2249 off += scnprintf(strbuf + off, size - off,
2250 "Local Doorbell state\t- 0x%08x\n", data);
2251 data = idt_nt_read(ndev, IDT_NT_INDBELLMSK);
2252 off += scnprintf(strbuf + off, size - off,
2253 "Local Doorbell mask\t- 0x%08x\n", data);
2254 off += scnprintf(strbuf + off, size - off, "\n");
2255
2256
2257 off += scnprintf(strbuf + off, size - off,
2258 "Message event valid\t- 0x%08x\n", IDT_MSG_MASK);
2259 data = idt_ntb_msg_read_sts(&ndev->ntb);
2260 off += scnprintf(strbuf + off, size - off,
2261 "Message event status\t- 0x%08x\n", data);
2262 data = idt_nt_read(ndev, IDT_NT_MSGSTSMSK);
2263 off += scnprintf(strbuf + off, size - off,
2264 "Message event mask\t- 0x%08x\n", data);
2265 off += scnprintf(strbuf + off, size - off,
2266 "Message data:\n");
2267 for (idx = 0; idx < IDT_MSG_CNT; idx++) {
2268 int src;
2269 data = idt_ntb_msg_read(&ndev->ntb, &src, idx);
2270 off += scnprintf(strbuf + off, size - off,
2271 "\t%hhu. 0x%08x from peer %hhu (Port %hhu)\n",
2272 idx, data, src, ndev->peers[src].port);
2273 }
2274 off += scnprintf(strbuf + off, size - off, "\n");
2275
2276
2277 idt_read_temp(ndev, &temp, &frac);
2278 off += scnprintf(strbuf + off, size - off,
2279 "Switch temperature\t\t- %hhu.%hhuC\n", temp, frac);
2280
2281
2282 ret = simple_read_from_buffer(ubuf, count, offp, strbuf, off);
2283 kfree(strbuf);
2284
2285 return ret;
2286}
2287
2288
2289
2290
2291
2292
2293
2294static int idt_init_dbgfs(struct idt_ntb_dev *ndev)
2295{
2296 char devname[64];
2297
2298
2299 if (IS_ERR_OR_NULL(dbgfs_topdir)) {
2300 dev_info(&ndev->ntb.pdev->dev, "Top DebugFS directory absent");
2301 return PTR_ERR(dbgfs_topdir);
2302 }
2303
2304
2305 snprintf(devname, 64, "info:%s", pci_name(ndev->ntb.pdev));
2306 ndev->dbgfs_info = debugfs_create_file(devname, 0400, dbgfs_topdir,
2307 ndev, &idt_dbgfs_info_ops);
2308 if (IS_ERR(ndev->dbgfs_info)) {
2309 dev_dbg(&ndev->ntb.pdev->dev, "Failed to create DebugFS node");
2310 return PTR_ERR(ndev->dbgfs_info);
2311 }
2312
2313 dev_dbg(&ndev->ntb.pdev->dev, "NTB device DebugFS node created");
2314
2315 return 0;
2316}
2317
2318
2319
2320
2321
2322
2323
2324static void idt_deinit_dbgfs(struct idt_ntb_dev *ndev)
2325{
2326 debugfs_remove(ndev->dbgfs_info);
2327
2328 dev_dbg(&ndev->ntb.pdev->dev, "NTB device DebugFS node discarded");
2329}
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343static int idt_check_setup(struct pci_dev *pdev)
2344{
2345 u32 data;
2346 int ret;
2347
2348
2349 ret = pci_read_config_dword(pdev, IDT_NT_BARSETUP0, &data);
2350 if (ret != 0) {
2351 dev_err(&pdev->dev,
2352 "Failed to read BARSETUP0 config register");
2353 return ret;
2354 }
2355
2356
2357 if (!(data & IDT_BARSETUP_EN) || !(data & IDT_BARSETUP_MODE_CFG)) {
2358 dev_err(&pdev->dev, "BAR0 doesn't map config space");
2359 return -EINVAL;
2360 }
2361
2362
2363 if ((data & IDT_BARSETUP_SIZE_MASK) != IDT_BARSETUP_SIZE_CFG) {
2364 dev_err(&pdev->dev, "Invalid size of config space");
2365 return -EINVAL;
2366 }
2367
2368 dev_dbg(&pdev->dev, "NTB device pre-initialized correctly");
2369
2370 return 0;
2371}
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386static struct idt_ntb_dev *idt_create_dev(struct pci_dev *pdev,
2387 const struct pci_device_id *id)
2388{
2389 struct idt_ntb_dev *ndev;
2390
2391
2392 ndev = devm_kzalloc(&pdev->dev, sizeof(*ndev), GFP_KERNEL);
2393 if (IS_ERR_OR_NULL(ndev)) {
2394 dev_err(&pdev->dev, "Memory allocation failed for descriptor");
2395 return ERR_PTR(-ENOMEM);
2396 }
2397
2398
2399 ndev->swcfg = (struct idt_89hpes_cfg *)id->driver_data;
2400
2401 ndev->ntb.pdev = pdev;
2402
2403
2404 spin_lock_init(&ndev->db_mask_lock);
2405 spin_lock_init(&ndev->msg_mask_lock);
2406 spin_lock_init(&ndev->gasa_lock);
2407
2408 dev_info(&pdev->dev, "IDT %s discovered", ndev->swcfg->name);
2409
2410 dev_dbg(&pdev->dev, "NTB device descriptor created");
2411
2412 return ndev;
2413}
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424static int idt_init_pci(struct idt_ntb_dev *ndev)
2425{
2426 struct pci_dev *pdev = ndev->ntb.pdev;
2427 int ret;
2428
2429
2430 ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
2431 if (ret != 0) {
2432 ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
2433 if (ret != 0) {
2434 dev_err(&pdev->dev, "Failed to set DMA bit mask\n");
2435 return ret;
2436 }
2437 dev_warn(&pdev->dev, "Cannot set DMA highmem bit mask\n");
2438 }
2439 ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
2440 if (ret != 0) {
2441 ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
2442 if (ret != 0) {
2443 dev_err(&pdev->dev,
2444 "Failed to set consistent DMA bit mask\n");
2445 return ret;
2446 }
2447 dev_warn(&pdev->dev,
2448 "Cannot set consistent DMA highmem bit mask\n");
2449 }
2450 ret = dma_coerce_mask_and_coherent(&ndev->ntb.dev,
2451 dma_get_mask(&pdev->dev));
2452 if (ret != 0) {
2453 dev_err(&pdev->dev, "Failed to set NTB device DMA bit mask\n");
2454 return ret;
2455 }
2456
2457
2458
2459
2460
2461 ret = pci_enable_pcie_error_reporting(pdev);
2462 if (ret != 0)
2463 dev_warn(&pdev->dev, "PCIe AER capability disabled\n");
2464 else
2465 pci_cleanup_aer_uncorrect_error_status(pdev);
2466
2467
2468 ret = pcim_enable_device(pdev);
2469 if (ret != 0) {
2470 dev_err(&pdev->dev, "Failed to enable PCIe device\n");
2471 goto err_disable_aer;
2472 }
2473
2474
2475
2476
2477
2478 pci_set_master(pdev);
2479
2480
2481 ret = pcim_iomap_regions_request_all(pdev, 1, NTB_NAME);
2482 if (ret != 0) {
2483 dev_err(&pdev->dev, "Failed to request resources\n");
2484 goto err_clear_master;
2485 }
2486
2487
2488 ndev->cfgspc = pcim_iomap_table(pdev)[0];
2489
2490
2491 pci_set_drvdata(pdev, ndev);
2492
2493 dev_dbg(&pdev->dev, "NT-function PCIe interface initialized");
2494
2495 return 0;
2496
2497err_clear_master:
2498 pci_clear_master(pdev);
2499err_disable_aer:
2500 (void)pci_disable_pcie_error_reporting(pdev);
2501
2502 return ret;
2503}
2504
2505
2506
2507
2508
2509
2510
2511static void idt_deinit_pci(struct idt_ntb_dev *ndev)
2512{
2513 struct pci_dev *pdev = ndev->ntb.pdev;
2514
2515
2516 pci_set_drvdata(pdev, NULL);
2517
2518
2519 pci_clear_master(pdev);
2520
2521
2522 (void)pci_disable_pcie_error_reporting(pdev);
2523
2524 dev_dbg(&pdev->dev, "NT-function PCIe interface cleared");
2525}
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539static int idt_pci_probe(struct pci_dev *pdev,
2540 const struct pci_device_id *id)
2541{
2542 struct idt_ntb_dev *ndev;
2543 int ret;
2544
2545
2546 ret = idt_check_setup(pdev);
2547 if (ret != 0)
2548 return ret;
2549
2550
2551 ndev = idt_create_dev(pdev, id);
2552 if (IS_ERR_OR_NULL(ndev))
2553 return PTR_ERR(ndev);
2554
2555
2556 ret = idt_init_pci(ndev);
2557 if (ret != 0)
2558 return ret;
2559
2560
2561 (void)idt_scan_ports(ndev);
2562
2563
2564 idt_init_link(ndev);
2565
2566
2567 ret = idt_init_mws(ndev);
2568 if (ret != 0)
2569 goto err_deinit_link;
2570
2571
2572 idt_init_msg(ndev);
2573
2574
2575 ret = idt_init_isr(ndev);
2576 if (ret != 0)
2577 goto err_deinit_link;
2578
2579
2580 ret = idt_register_device(ndev);
2581 if (ret != 0)
2582 goto err_deinit_isr;
2583
2584
2585 (void)idt_init_dbgfs(ndev);
2586
2587
2588 dev_info(&pdev->dev, "IDT NTB device is ready");
2589
2590
2591 return 0;
2592
2593err_deinit_isr:
2594 idt_deinit_isr(ndev);
2595err_deinit_link:
2596 idt_deinit_link(ndev);
2597 idt_deinit_pci(ndev);
2598
2599 return ret;
2600}
2601
2602
2603
2604
2605
2606static void idt_pci_remove(struct pci_dev *pdev)
2607{
2608 struct idt_ntb_dev *ndev = pci_get_drvdata(pdev);
2609
2610
2611 idt_deinit_dbgfs(ndev);
2612
2613
2614 idt_unregister_device(ndev);
2615
2616
2617 idt_deinit_isr(ndev);
2618
2619
2620 idt_deinit_link(ndev);
2621
2622
2623 idt_deinit_pci(ndev);
2624
2625
2626 dev_info(&pdev->dev, "IDT NTB device is removed");
2627
2628
2629}
2630
2631
2632
2633
2634static const struct idt_89hpes_cfg idt_89hpes24nt6ag2_config = {
2635 .name = "89HPES24NT6AG2",
2636 .port_cnt = 6, .ports = {0, 2, 4, 6, 8, 12}
2637};
2638static const struct idt_89hpes_cfg idt_89hpes32nt8ag2_config = {
2639 .name = "89HPES32NT8AG2",
2640 .port_cnt = 8, .ports = {0, 2, 4, 6, 8, 12, 16, 20}
2641};
2642static const struct idt_89hpes_cfg idt_89hpes32nt8bg2_config = {
2643 .name = "89HPES32NT8BG2",
2644 .port_cnt = 8, .ports = {0, 2, 4, 6, 8, 12, 16, 20}
2645};
2646static const struct idt_89hpes_cfg idt_89hpes12nt12g2_config = {
2647 .name = "89HPES12NT12G2",
2648 .port_cnt = 3, .ports = {0, 8, 16}
2649};
2650static const struct idt_89hpes_cfg idt_89hpes16nt16g2_config = {
2651 .name = "89HPES16NT16G2",
2652 .port_cnt = 4, .ports = {0, 8, 12, 16}
2653};
2654static const struct idt_89hpes_cfg idt_89hpes24nt24g2_config = {
2655 .name = "89HPES24NT24G2",
2656 .port_cnt = 8, .ports = {0, 2, 4, 6, 8, 12, 16, 20}
2657};
2658static const struct idt_89hpes_cfg idt_89hpes32nt24ag2_config = {
2659 .name = "89HPES32NT24AG2",
2660 .port_cnt = 8, .ports = {0, 2, 4, 6, 8, 12, 16, 20}
2661};
2662static const struct idt_89hpes_cfg idt_89hpes32nt24bg2_config = {
2663 .name = "89HPES32NT24BG2",
2664 .port_cnt = 8, .ports = {0, 2, 4, 6, 8, 12, 16, 20}
2665};
2666
2667
2668
2669
2670static const struct pci_device_id idt_pci_tbl[] = {
2671 {IDT_PCI_DEVICE_IDS(89HPES24NT6AG2, idt_89hpes24nt6ag2_config)},
2672 {IDT_PCI_DEVICE_IDS(89HPES32NT8AG2, idt_89hpes32nt8ag2_config)},
2673 {IDT_PCI_DEVICE_IDS(89HPES32NT8BG2, idt_89hpes32nt8bg2_config)},
2674 {IDT_PCI_DEVICE_IDS(89HPES12NT12G2, idt_89hpes12nt12g2_config)},
2675 {IDT_PCI_DEVICE_IDS(89HPES16NT16G2, idt_89hpes16nt16g2_config)},
2676 {IDT_PCI_DEVICE_IDS(89HPES24NT24G2, idt_89hpes24nt24g2_config)},
2677 {IDT_PCI_DEVICE_IDS(89HPES32NT24AG2, idt_89hpes32nt24ag2_config)},
2678 {IDT_PCI_DEVICE_IDS(89HPES32NT24BG2, idt_89hpes32nt24bg2_config)},
2679 {0}
2680};
2681MODULE_DEVICE_TABLE(pci, idt_pci_tbl);
2682
2683
2684
2685
2686static struct pci_driver idt_pci_driver = {
2687 .name = KBUILD_MODNAME,
2688 .probe = idt_pci_probe,
2689 .remove = idt_pci_remove,
2690 .id_table = idt_pci_tbl,
2691};
2692
2693static int __init idt_pci_driver_init(void)
2694{
2695 pr_info("%s %s\n", NTB_DESC, NTB_VER);
2696
2697
2698 if (debugfs_initialized())
2699 dbgfs_topdir = debugfs_create_dir(KBUILD_MODNAME, NULL);
2700
2701
2702 return pci_register_driver(&idt_pci_driver);
2703}
2704module_init(idt_pci_driver_init);
2705
2706static void __exit idt_pci_driver_exit(void)
2707{
2708
2709 pci_unregister_driver(&idt_pci_driver);
2710
2711
2712 debugfs_remove_recursive(dbgfs_topdir);
2713}
2714module_exit(idt_pci_driver_exit);
2715
2716