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
1754
1755static int idt_ntb_msg_read(struct ntb_dev *ntb, int midx, int *pidx, u32 *msg)
1756{
1757 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
1758
1759 if (midx < 0 || IDT_MSG_CNT <= midx)
1760 return -EINVAL;
1761
1762
1763 if (pidx != NULL) {
1764 u32 srcpart;
1765
1766 srcpart = idt_nt_read(ndev, ntdata_tbl.msgs[midx].src);
1767 *pidx = ndev->part_idx_map[srcpart];
1768
1769
1770 if (*pidx == -EINVAL)
1771 *pidx = 0;
1772 }
1773
1774
1775 if (msg != NULL)
1776 *msg = idt_nt_read(ndev, ntdata_tbl.msgs[midx].in);
1777
1778 return 0;
1779}
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794static int idt_ntb_msg_write(struct ntb_dev *ntb, int midx, int pidx, u32 msg)
1795{
1796 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
1797 unsigned long irqflags;
1798 u32 swpmsgctl = 0;
1799
1800 if (midx < 0 || IDT_MSG_CNT <= midx)
1801 return -EINVAL;
1802
1803 if (pidx < 0 || ndev->peer_cnt <= pidx)
1804 return -EINVAL;
1805
1806
1807 swpmsgctl = SET_FIELD(SWPxMSGCTL_REG, 0, midx) |
1808 SET_FIELD(SWPxMSGCTL_PART, 0, ndev->peers[pidx].part);
1809
1810
1811 spin_lock_irqsave(&ndev->msg_locks[midx], irqflags);
1812
1813 idt_sw_write(ndev, partdata_tbl[ndev->part].msgctl[midx], swpmsgctl);
1814 idt_nt_write(ndev, ntdata_tbl.msgs[midx].out, msg);
1815 mmiowb();
1816
1817 spin_unlock_irqrestore(&ndev->msg_locks[midx], irqflags);
1818
1819
1820 return 0;
1821}
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840static void idt_read_temp(struct idt_ntb_dev *ndev, unsigned char *val,
1841 unsigned char *frac)
1842{
1843 u32 data;
1844
1845
1846 data = idt_sw_read(ndev, IDT_SW_TMPSTS);
1847 data = GET_FIELD(TMPSTS_TEMP, data);
1848
1849 *val = data >> 1;
1850 *frac = ((data & 0x1) ? 5 : 0);
1851}
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864static void idt_temp_isr(struct idt_ntb_dev *ndev, u32 ntint_sts)
1865{
1866 unsigned char val, frac;
1867
1868
1869 idt_read_temp(ndev, &val, &frac);
1870
1871
1872
1873
1874
1875 idt_nt_write(ndev, IDT_NT_NTINTSTS, IDT_NTINTSTS_TMPSENSOR);
1876
1877 dev_dbg(&ndev->ntb.pdev->dev,
1878 "Temp sensor IRQ detected %#08x", ntint_sts);
1879
1880
1881 dev_warn(&ndev->ntb.pdev->dev, "Temperature %hhu.%hhu", val, frac);
1882}
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901static irqreturn_t idt_thread_isr(int irq, void *devid);
1902
1903
1904
1905
1906
1907
1908
1909static int idt_init_isr(struct idt_ntb_dev *ndev)
1910{
1911 struct pci_dev *pdev = ndev->ntb.pdev;
1912 u32 ntint_mask;
1913 int ret;
1914
1915
1916 ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI | PCI_IRQ_LEGACY);
1917 if (ret != 1) {
1918 dev_err(&pdev->dev, "Failed to allocate IRQ vector");
1919 return ret;
1920 }
1921
1922
1923 ret = pci_irq_vector(pdev, 0);
1924 if (ret < 0) {
1925 dev_err(&pdev->dev, "Failed to get IRQ vector");
1926 goto err_free_vectors;
1927 }
1928
1929
1930 ret = devm_request_threaded_irq(&pdev->dev, ret, NULL, idt_thread_isr,
1931 IRQF_ONESHOT, NTB_IRQNAME, ndev);
1932 if (ret != 0) {
1933 dev_err(&pdev->dev, "Failed to set MSI IRQ handler, %d", ret);
1934 goto err_free_vectors;
1935 }
1936
1937
1938 ntint_mask = idt_nt_read(ndev, IDT_NT_NTINTMSK) & ~IDT_NTINTMSK_ALL;
1939 idt_nt_write(ndev, IDT_NT_NTINTMSK, ntint_mask);
1940
1941
1942 dev_dbg(&pdev->dev, "NTB interrupts initialized");
1943
1944 return 0;
1945
1946err_free_vectors:
1947 pci_free_irq_vectors(pdev);
1948
1949 return ret;
1950}
1951
1952
1953
1954
1955
1956
1957
1958
1959static void idt_deinit_isr(struct idt_ntb_dev *ndev)
1960{
1961 struct pci_dev *pdev = ndev->ntb.pdev;
1962 u32 ntint_mask;
1963
1964
1965 ntint_mask = idt_nt_read(ndev, IDT_NT_NTINTMSK) | IDT_NTINTMSK_ALL;
1966 idt_nt_write(ndev, IDT_NT_NTINTMSK, ntint_mask);
1967
1968
1969 devm_free_irq(&pdev->dev, pci_irq_vector(pdev, 0), ndev);
1970
1971
1972 pci_free_irq_vectors(pdev);
1973
1974 dev_dbg(&pdev->dev, "NTB interrupts deinitialized");
1975}
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986static irqreturn_t idt_thread_isr(int irq, void *devid)
1987{
1988 struct idt_ntb_dev *ndev = devid;
1989 bool handled = false;
1990 u32 ntint_sts;
1991
1992
1993 ntint_sts = idt_nt_read(ndev, IDT_NT_NTINTSTS);
1994
1995
1996 if (ntint_sts & IDT_NTINTSTS_MSG) {
1997 idt_msg_isr(ndev, ntint_sts);
1998 handled = true;
1999 }
2000
2001
2002 if (ntint_sts & IDT_NTINTSTS_DBELL) {
2003 idt_db_isr(ndev, ntint_sts);
2004 handled = true;
2005 }
2006
2007
2008 if (ntint_sts & IDT_NTINTSTS_SEVENT) {
2009 idt_se_isr(ndev, ntint_sts);
2010 handled = true;
2011 }
2012
2013
2014 if (ntint_sts & IDT_NTINTSTS_TMPSENSOR) {
2015 idt_temp_isr(ndev, ntint_sts);
2016 handled = true;
2017 }
2018
2019 dev_dbg(&ndev->ntb.pdev->dev, "IDT IRQs 0x%08x handled", ntint_sts);
2020
2021 return handled ? IRQ_HANDLED : IRQ_NONE;
2022}
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032static const struct ntb_dev_ops idt_ntb_ops = {
2033 .port_number = idt_ntb_port_number,
2034 .peer_port_count = idt_ntb_peer_port_count,
2035 .peer_port_number = idt_ntb_peer_port_number,
2036 .peer_port_idx = idt_ntb_peer_port_idx,
2037 .link_is_up = idt_ntb_link_is_up,
2038 .link_enable = idt_ntb_link_enable,
2039 .link_disable = idt_ntb_link_disable,
2040 .mw_count = idt_ntb_mw_count,
2041 .mw_get_align = idt_ntb_mw_get_align,
2042 .peer_mw_count = idt_ntb_peer_mw_count,
2043 .peer_mw_get_addr = idt_ntb_peer_mw_get_addr,
2044 .peer_mw_set_trans = idt_ntb_peer_mw_set_trans,
2045 .peer_mw_clear_trans = idt_ntb_peer_mw_clear_trans,
2046 .db_valid_mask = idt_ntb_db_valid_mask,
2047 .db_read = idt_ntb_db_read,
2048 .db_clear = idt_ntb_db_clear,
2049 .db_read_mask = idt_ntb_db_read_mask,
2050 .db_set_mask = idt_ntb_db_set_mask,
2051 .db_clear_mask = idt_ntb_db_clear_mask,
2052 .peer_db_set = idt_ntb_peer_db_set,
2053 .msg_count = idt_ntb_msg_count,
2054 .msg_inbits = idt_ntb_msg_inbits,
2055 .msg_outbits = idt_ntb_msg_outbits,
2056 .msg_read_sts = idt_ntb_msg_read_sts,
2057 .msg_clear_sts = idt_ntb_msg_clear_sts,
2058 .msg_set_mask = idt_ntb_msg_set_mask,
2059 .msg_clear_mask = idt_ntb_msg_clear_mask,
2060 .msg_read = idt_ntb_msg_read,
2061 .msg_write = idt_ntb_msg_write
2062};
2063
2064
2065
2066
2067
2068
2069
2070static int idt_register_device(struct idt_ntb_dev *ndev)
2071{
2072 int ret;
2073
2074
2075 ndev->ntb.ops = &idt_ntb_ops;
2076 ndev->ntb.topo = NTB_TOPO_PRI;
2077
2078 ret = ntb_register_device(&ndev->ntb);
2079 if (ret != 0) {
2080 dev_err(&ndev->ntb.pdev->dev, "Failed to register NTB device");
2081 return ret;
2082 }
2083
2084 dev_dbg(&ndev->ntb.pdev->dev, "NTB device successfully registered");
2085
2086 return 0;
2087}
2088
2089
2090
2091
2092
2093static void idt_unregister_device(struct idt_ntb_dev *ndev)
2094{
2095
2096 ntb_unregister_device(&ndev->ntb);
2097
2098 dev_dbg(&ndev->ntb.pdev->dev, "NTB device unregistered");
2099}
2100
2101
2102
2103
2104
2105
2106static ssize_t idt_dbgfs_info_read(struct file *filp, char __user *ubuf,
2107 size_t count, loff_t *offp);
2108
2109
2110
2111
2112static const struct file_operations idt_dbgfs_info_ops = {
2113 .owner = THIS_MODULE,
2114 .open = simple_open,
2115 .read = idt_dbgfs_info_read
2116};
2117
2118
2119
2120
2121
2122
2123
2124
2125static ssize_t idt_dbgfs_info_read(struct file *filp, char __user *ubuf,
2126 size_t count, loff_t *offp)
2127{
2128 struct idt_ntb_dev *ndev = filp->private_data;
2129 unsigned char temp, frac, idx, pidx, cnt;
2130 ssize_t ret = 0, off = 0;
2131 unsigned long irqflags;
2132 enum ntb_speed speed;
2133 enum ntb_width width;
2134 char *strbuf;
2135 size_t size;
2136 u32 data;
2137
2138
2139 size = min_t(size_t, count, 0x1000U);
2140
2141
2142 strbuf = kmalloc(size, GFP_KERNEL);
2143 if (strbuf == NULL)
2144 return -ENOMEM;
2145
2146
2147 off += scnprintf(strbuf + off, size - off,
2148 "\n\t\tIDT NTB device Information:\n\n");
2149
2150
2151 off += scnprintf(strbuf + off, size - off,
2152 "Local Port %hhu, Partition %hhu\n", ndev->port, ndev->part);
2153
2154
2155 off += scnprintf(strbuf + off, size - off, "Peers:\n");
2156 for (idx = 0; idx < ndev->peer_cnt; idx++) {
2157 off += scnprintf(strbuf + off, size - off,
2158 "\t%hhu. Port %hhu, Partition %hhu\n",
2159 idx, ndev->peers[idx].port, ndev->peers[idx].part);
2160 }
2161
2162
2163 data = idt_ntb_link_is_up(&ndev->ntb, &speed, &width);
2164 off += scnprintf(strbuf + off, size - off,
2165 "NTB link status\t- 0x%08x, ", data);
2166 off += scnprintf(strbuf + off, size - off, "PCIe Gen %d x%d lanes\n",
2167 speed, width);
2168
2169
2170 off += scnprintf(strbuf + off, size - off, "NTB Mapping Table:\n");
2171 for (idx = 0; idx < IDT_MTBL_ENTRY_CNT; idx++) {
2172 spin_lock_irqsave(&ndev->mtbl_lock, irqflags);
2173 idt_nt_write(ndev, IDT_NT_NTMTBLADDR, idx);
2174 data = idt_nt_read(ndev, IDT_NT_NTMTBLDATA);
2175 spin_unlock_irqrestore(&ndev->mtbl_lock, irqflags);
2176
2177
2178 if (data & IDT_NTMTBLDATA_VALID) {
2179 off += scnprintf(strbuf + off, size - off,
2180 "\t%hhu. Partition %d, Requester ID 0x%04x\n",
2181 idx, GET_FIELD(NTMTBLDATA_PART, data),
2182 GET_FIELD(NTMTBLDATA_REQID, data));
2183 }
2184 }
2185 off += scnprintf(strbuf + off, size - off, "\n");
2186
2187
2188 off += scnprintf(strbuf + off, size - off,
2189 "Outbound Memory Windows:\n");
2190 for (idx = 0; idx < ndev->mw_cnt; idx += cnt) {
2191 data = ndev->mws[idx].type;
2192 cnt = idt_get_mw_count(data);
2193
2194
2195 if (data == IDT_MW_DIR)
2196 off += scnprintf(strbuf + off, size - off,
2197 "\t%hhu.\t", idx);
2198 else
2199 off += scnprintf(strbuf + off, size - off,
2200 "\t%hhu-%hhu.\t", idx, idx + cnt - 1);
2201
2202 off += scnprintf(strbuf + off, size - off, "%s BAR%hhu, ",
2203 idt_get_mw_name(data), ndev->mws[idx].bar);
2204
2205 off += scnprintf(strbuf + off, size - off,
2206 "Address align 0x%08llx, ", ndev->mws[idx].addr_align);
2207
2208 off += scnprintf(strbuf + off, size - off,
2209 "Size align 0x%08llx, Size max %llu\n",
2210 ndev->mws[idx].size_align, ndev->mws[idx].size_max);
2211 }
2212
2213
2214 for (pidx = 0; pidx < ndev->peer_cnt; pidx++) {
2215 off += scnprintf(strbuf + off, size - off,
2216 "Inbound Memory Windows for peer %hhu (Port %hhu):\n",
2217 pidx, ndev->peers[pidx].port);
2218
2219
2220 for (idx = 0; idx < ndev->peers[pidx].mw_cnt; idx += cnt) {
2221 data = ndev->peers[pidx].mws[idx].type;
2222 cnt = idt_get_mw_count(data);
2223
2224 if (data == IDT_MW_DIR)
2225 off += scnprintf(strbuf + off, size - off,
2226 "\t%hhu.\t", idx);
2227 else
2228 off += scnprintf(strbuf + off, size - off,
2229 "\t%hhu-%hhu.\t", idx, idx + cnt - 1);
2230
2231 off += scnprintf(strbuf + off, size - off,
2232 "%s BAR%hhu, ", idt_get_mw_name(data),
2233 ndev->peers[pidx].mws[idx].bar);
2234
2235 off += scnprintf(strbuf + off, size - off,
2236 "Address align 0x%08llx, ",
2237 ndev->peers[pidx].mws[idx].addr_align);
2238
2239 off += scnprintf(strbuf + off, size - off,
2240 "Size align 0x%08llx, Size max %llu\n",
2241 ndev->peers[pidx].mws[idx].size_align,
2242 ndev->peers[pidx].mws[idx].size_max);
2243 }
2244 }
2245 off += scnprintf(strbuf + off, size - off, "\n");
2246
2247
2248 data = idt_sw_read(ndev, IDT_SW_GDBELLSTS);
2249 off += scnprintf(strbuf + off, size - off,
2250 "Global Doorbell state\t- 0x%08x\n", data);
2251 data = idt_ntb_db_read(&ndev->ntb);
2252 off += scnprintf(strbuf + off, size - off,
2253 "Local Doorbell state\t- 0x%08x\n", data);
2254 data = idt_nt_read(ndev, IDT_NT_INDBELLMSK);
2255 off += scnprintf(strbuf + off, size - off,
2256 "Local Doorbell mask\t- 0x%08x\n", data);
2257 off += scnprintf(strbuf + off, size - off, "\n");
2258
2259
2260 off += scnprintf(strbuf + off, size - off,
2261 "Message event valid\t- 0x%08x\n", IDT_MSG_MASK);
2262 data = idt_ntb_msg_read_sts(&ndev->ntb);
2263 off += scnprintf(strbuf + off, size - off,
2264 "Message event status\t- 0x%08x\n", data);
2265 data = idt_nt_read(ndev, IDT_NT_MSGSTSMSK);
2266 off += scnprintf(strbuf + off, size - off,
2267 "Message event mask\t- 0x%08x\n", data);
2268 off += scnprintf(strbuf + off, size - off,
2269 "Message data:\n");
2270 for (idx = 0; idx < IDT_MSG_CNT; idx++) {
2271 int src;
2272 (void)idt_ntb_msg_read(&ndev->ntb, idx, &src, &data);
2273 off += scnprintf(strbuf + off, size - off,
2274 "\t%hhu. 0x%08x from peer %hhu (Port %hhu)\n",
2275 idx, data, src, ndev->peers[src].port);
2276 }
2277 off += scnprintf(strbuf + off, size - off, "\n");
2278
2279
2280 idt_read_temp(ndev, &temp, &frac);
2281 off += scnprintf(strbuf + off, size - off,
2282 "Switch temperature\t\t- %hhu.%hhuC\n", temp, frac);
2283
2284
2285 ret = simple_read_from_buffer(ubuf, count, offp, strbuf, off);
2286 kfree(strbuf);
2287
2288 return ret;
2289}
2290
2291
2292
2293
2294
2295
2296
2297static int idt_init_dbgfs(struct idt_ntb_dev *ndev)
2298{
2299 char devname[64];
2300
2301
2302 if (IS_ERR_OR_NULL(dbgfs_topdir)) {
2303 dev_info(&ndev->ntb.pdev->dev, "Top DebugFS directory absent");
2304 return PTR_ERR(dbgfs_topdir);
2305 }
2306
2307
2308 snprintf(devname, 64, "info:%s", pci_name(ndev->ntb.pdev));
2309 ndev->dbgfs_info = debugfs_create_file(devname, 0400, dbgfs_topdir,
2310 ndev, &idt_dbgfs_info_ops);
2311 if (IS_ERR(ndev->dbgfs_info)) {
2312 dev_dbg(&ndev->ntb.pdev->dev, "Failed to create DebugFS node");
2313 return PTR_ERR(ndev->dbgfs_info);
2314 }
2315
2316 dev_dbg(&ndev->ntb.pdev->dev, "NTB device DebugFS node created");
2317
2318 return 0;
2319}
2320
2321
2322
2323
2324
2325
2326
2327static void idt_deinit_dbgfs(struct idt_ntb_dev *ndev)
2328{
2329 debugfs_remove(ndev->dbgfs_info);
2330
2331 dev_dbg(&ndev->ntb.pdev->dev, "NTB device DebugFS node discarded");
2332}
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346static int idt_check_setup(struct pci_dev *pdev)
2347{
2348 u32 data;
2349 int ret;
2350
2351
2352 ret = pci_read_config_dword(pdev, IDT_NT_BARSETUP0, &data);
2353 if (ret != 0) {
2354 dev_err(&pdev->dev,
2355 "Failed to read BARSETUP0 config register");
2356 return ret;
2357 }
2358
2359
2360 if (!(data & IDT_BARSETUP_EN) || !(data & IDT_BARSETUP_MODE_CFG)) {
2361 dev_err(&pdev->dev, "BAR0 doesn't map config space");
2362 return -EINVAL;
2363 }
2364
2365
2366 if ((data & IDT_BARSETUP_SIZE_MASK) != IDT_BARSETUP_SIZE_CFG) {
2367 dev_err(&pdev->dev, "Invalid size of config space");
2368 return -EINVAL;
2369 }
2370
2371 dev_dbg(&pdev->dev, "NTB device pre-initialized correctly");
2372
2373 return 0;
2374}
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389static struct idt_ntb_dev *idt_create_dev(struct pci_dev *pdev,
2390 const struct pci_device_id *id)
2391{
2392 struct idt_ntb_dev *ndev;
2393
2394
2395 ndev = devm_kzalloc(&pdev->dev, sizeof(*ndev), GFP_KERNEL);
2396 if (IS_ERR_OR_NULL(ndev)) {
2397 dev_err(&pdev->dev, "Memory allocation failed for descriptor");
2398 return ERR_PTR(-ENOMEM);
2399 }
2400
2401
2402 ndev->swcfg = (struct idt_89hpes_cfg *)id->driver_data;
2403
2404 ndev->ntb.pdev = pdev;
2405
2406
2407 spin_lock_init(&ndev->db_mask_lock);
2408 spin_lock_init(&ndev->msg_mask_lock);
2409 spin_lock_init(&ndev->gasa_lock);
2410
2411 dev_info(&pdev->dev, "IDT %s discovered", ndev->swcfg->name);
2412
2413 dev_dbg(&pdev->dev, "NTB device descriptor created");
2414
2415 return ndev;
2416}
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427static int idt_init_pci(struct idt_ntb_dev *ndev)
2428{
2429 struct pci_dev *pdev = ndev->ntb.pdev;
2430 int ret;
2431
2432
2433 ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
2434 if (ret != 0) {
2435 ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
2436 if (ret != 0) {
2437 dev_err(&pdev->dev, "Failed to set DMA bit mask\n");
2438 return ret;
2439 }
2440 dev_warn(&pdev->dev, "Cannot set DMA highmem bit mask\n");
2441 }
2442 ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
2443 if (ret != 0) {
2444 ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
2445 if (ret != 0) {
2446 dev_err(&pdev->dev,
2447 "Failed to set consistent DMA bit mask\n");
2448 return ret;
2449 }
2450 dev_warn(&pdev->dev,
2451 "Cannot set consistent DMA highmem bit mask\n");
2452 }
2453
2454
2455
2456
2457
2458 ret = pci_enable_pcie_error_reporting(pdev);
2459 if (ret != 0)
2460 dev_warn(&pdev->dev, "PCIe AER capability disabled\n");
2461 else
2462 pci_cleanup_aer_uncorrect_error_status(pdev);
2463
2464
2465 ret = pcim_enable_device(pdev);
2466 if (ret != 0) {
2467 dev_err(&pdev->dev, "Failed to enable PCIe device\n");
2468 goto err_disable_aer;
2469 }
2470
2471
2472
2473
2474
2475 pci_set_master(pdev);
2476
2477
2478 ret = pcim_iomap_regions_request_all(pdev, 1, NTB_NAME);
2479 if (ret != 0) {
2480 dev_err(&pdev->dev, "Failed to request resources\n");
2481 goto err_clear_master;
2482 }
2483
2484
2485 ndev->cfgspc = pcim_iomap_table(pdev)[0];
2486
2487
2488 pci_set_drvdata(pdev, ndev);
2489
2490 dev_dbg(&pdev->dev, "NT-function PCIe interface initialized");
2491
2492 return 0;
2493
2494err_clear_master:
2495 pci_clear_master(pdev);
2496err_disable_aer:
2497 (void)pci_disable_pcie_error_reporting(pdev);
2498
2499 return ret;
2500}
2501
2502
2503
2504
2505
2506
2507
2508static void idt_deinit_pci(struct idt_ntb_dev *ndev)
2509{
2510 struct pci_dev *pdev = ndev->ntb.pdev;
2511
2512
2513 pci_set_drvdata(pdev, NULL);
2514
2515
2516 pci_clear_master(pdev);
2517
2518
2519 (void)pci_disable_pcie_error_reporting(pdev);
2520
2521 dev_dbg(&pdev->dev, "NT-function PCIe interface cleared");
2522}
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536static int idt_pci_probe(struct pci_dev *pdev,
2537 const struct pci_device_id *id)
2538{
2539 struct idt_ntb_dev *ndev;
2540 int ret;
2541
2542
2543 ret = idt_check_setup(pdev);
2544 if (ret != 0)
2545 return ret;
2546
2547
2548 ndev = idt_create_dev(pdev, id);
2549 if (IS_ERR_OR_NULL(ndev))
2550 return PTR_ERR(ndev);
2551
2552
2553 ret = idt_init_pci(ndev);
2554 if (ret != 0)
2555 return ret;
2556
2557
2558 (void)idt_scan_ports(ndev);
2559
2560
2561 idt_init_link(ndev);
2562
2563
2564 ret = idt_init_mws(ndev);
2565 if (ret != 0)
2566 goto err_deinit_link;
2567
2568
2569 idt_init_msg(ndev);
2570
2571
2572 ret = idt_init_isr(ndev);
2573 if (ret != 0)
2574 goto err_deinit_link;
2575
2576
2577 ret = idt_register_device(ndev);
2578 if (ret != 0)
2579 goto err_deinit_isr;
2580
2581
2582 (void)idt_init_dbgfs(ndev);
2583
2584
2585 dev_info(&pdev->dev, "IDT NTB device is ready");
2586
2587
2588 return 0;
2589
2590err_deinit_isr:
2591 idt_deinit_isr(ndev);
2592err_deinit_link:
2593 idt_deinit_link(ndev);
2594 idt_deinit_pci(ndev);
2595
2596 return ret;
2597}
2598
2599
2600
2601
2602
2603static void idt_pci_remove(struct pci_dev *pdev)
2604{
2605 struct idt_ntb_dev *ndev = pci_get_drvdata(pdev);
2606
2607
2608 idt_deinit_dbgfs(ndev);
2609
2610
2611 idt_unregister_device(ndev);
2612
2613
2614 idt_deinit_isr(ndev);
2615
2616
2617 idt_deinit_link(ndev);
2618
2619
2620 idt_deinit_pci(ndev);
2621
2622
2623 dev_info(&pdev->dev, "IDT NTB device is removed");
2624
2625
2626}
2627
2628
2629
2630
2631static struct idt_89hpes_cfg idt_89hpes24nt6ag2_config = {
2632 .name = "89HPES24NT6AG2",
2633 .port_cnt = 6, .ports = {0, 2, 4, 6, 8, 12}
2634};
2635static struct idt_89hpes_cfg idt_89hpes32nt8ag2_config = {
2636 .name = "89HPES32NT8AG2",
2637 .port_cnt = 8, .ports = {0, 2, 4, 6, 8, 12, 16, 20}
2638};
2639static struct idt_89hpes_cfg idt_89hpes32nt8bg2_config = {
2640 .name = "89HPES32NT8BG2",
2641 .port_cnt = 8, .ports = {0, 2, 4, 6, 8, 12, 16, 20}
2642};
2643static struct idt_89hpes_cfg idt_89hpes12nt12g2_config = {
2644 .name = "89HPES12NT12G2",
2645 .port_cnt = 3, .ports = {0, 8, 16}
2646};
2647static struct idt_89hpes_cfg idt_89hpes16nt16g2_config = {
2648 .name = "89HPES16NT16G2",
2649 .port_cnt = 4, .ports = {0, 8, 12, 16}
2650};
2651static struct idt_89hpes_cfg idt_89hpes24nt24g2_config = {
2652 .name = "89HPES24NT24G2",
2653 .port_cnt = 8, .ports = {0, 2, 4, 6, 8, 12, 16, 20}
2654};
2655static struct idt_89hpes_cfg idt_89hpes32nt24ag2_config = {
2656 .name = "89HPES32NT24AG2",
2657 .port_cnt = 8, .ports = {0, 2, 4, 6, 8, 12, 16, 20}
2658};
2659static struct idt_89hpes_cfg idt_89hpes32nt24bg2_config = {
2660 .name = "89HPES32NT24BG2",
2661 .port_cnt = 8, .ports = {0, 2, 4, 6, 8, 12, 16, 20}
2662};
2663
2664
2665
2666
2667static const struct pci_device_id idt_pci_tbl[] = {
2668 {IDT_PCI_DEVICE_IDS(89HPES24NT6AG2, idt_89hpes24nt6ag2_config)},
2669 {IDT_PCI_DEVICE_IDS(89HPES32NT8AG2, idt_89hpes32nt8ag2_config)},
2670 {IDT_PCI_DEVICE_IDS(89HPES32NT8BG2, idt_89hpes32nt8bg2_config)},
2671 {IDT_PCI_DEVICE_IDS(89HPES12NT12G2, idt_89hpes12nt12g2_config)},
2672 {IDT_PCI_DEVICE_IDS(89HPES16NT16G2, idt_89hpes16nt16g2_config)},
2673 {IDT_PCI_DEVICE_IDS(89HPES24NT24G2, idt_89hpes24nt24g2_config)},
2674 {IDT_PCI_DEVICE_IDS(89HPES32NT24AG2, idt_89hpes32nt24ag2_config)},
2675 {IDT_PCI_DEVICE_IDS(89HPES32NT24BG2, idt_89hpes32nt24bg2_config)},
2676 {0}
2677};
2678MODULE_DEVICE_TABLE(pci, idt_pci_tbl);
2679
2680
2681
2682
2683static struct pci_driver idt_pci_driver = {
2684 .name = KBUILD_MODNAME,
2685 .probe = idt_pci_probe,
2686 .remove = idt_pci_remove,
2687 .id_table = idt_pci_tbl,
2688};
2689
2690static int __init idt_pci_driver_init(void)
2691{
2692 pr_info("%s %s\n", NTB_DESC, NTB_VER);
2693
2694
2695 if (debugfs_initialized())
2696 dbgfs_topdir = debugfs_create_dir(KBUILD_MODNAME, NULL);
2697
2698
2699 return pci_register_driver(&idt_pci_driver);
2700}
2701module_init(idt_pci_driver_init);
2702
2703static void __exit idt_pci_driver_exit(void)
2704{
2705
2706 pci_unregister_driver(&idt_pci_driver);
2707
2708
2709 debugfs_remove_recursive(dbgfs_topdir);
2710}
2711module_exit(idt_pci_driver_exit);
2712
2713