0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042 #include <linux/stddef.h>
0043 #include <linux/types.h>
0044 #include <linux/kernel.h>
0045 #include <linux/bitops.h>
0046 #include <linux/sizes.h>
0047 #include <linux/module.h>
0048 #include <linux/moduleparam.h>
0049 #include <linux/init.h>
0050 #include <linux/interrupt.h>
0051 #include <linux/spinlock.h>
0052 #include <linux/mutex.h>
0053 #include <linux/pci.h>
0054 #include <linux/aer.h>
0055 #include <linux/slab.h>
0056 #include <linux/list.h>
0057 #include <linux/debugfs.h>
0058 #include <linux/hwmon.h>
0059 #include <linux/hwmon-sysfs.h>
0060 #include <linux/ntb.h>
0061
0062 #include "ntb_hw_idt.h"
0063
0064 #define NTB_NAME "ntb_hw_idt"
0065 #define NTB_DESC "IDT PCI-E Non-Transparent Bridge Driver"
0066 #define NTB_VER "2.0"
0067 #define NTB_IRQNAME "ntb_irq_idt"
0068
0069 MODULE_DESCRIPTION(NTB_DESC);
0070 MODULE_VERSION(NTB_VER);
0071 MODULE_LICENSE("GPL v2");
0072 MODULE_AUTHOR("T-platforms");
0073
0074
0075
0076
0077
0078 static const struct idt_ntb_regs ntdata_tbl = {
0079 { {IDT_NT_BARSETUP0, IDT_NT_BARLIMIT0,
0080 IDT_NT_BARLTBASE0, IDT_NT_BARUTBASE0},
0081 {IDT_NT_BARSETUP1, IDT_NT_BARLIMIT1,
0082 IDT_NT_BARLTBASE1, IDT_NT_BARUTBASE1},
0083 {IDT_NT_BARSETUP2, IDT_NT_BARLIMIT2,
0084 IDT_NT_BARLTBASE2, IDT_NT_BARUTBASE2},
0085 {IDT_NT_BARSETUP3, IDT_NT_BARLIMIT3,
0086 IDT_NT_BARLTBASE3, IDT_NT_BARUTBASE3},
0087 {IDT_NT_BARSETUP4, IDT_NT_BARLIMIT4,
0088 IDT_NT_BARLTBASE4, IDT_NT_BARUTBASE4},
0089 {IDT_NT_BARSETUP5, IDT_NT_BARLIMIT5,
0090 IDT_NT_BARLTBASE5, IDT_NT_BARUTBASE5} },
0091 { {IDT_NT_INMSG0, IDT_NT_OUTMSG0, IDT_NT_INMSGSRC0},
0092 {IDT_NT_INMSG1, IDT_NT_OUTMSG1, IDT_NT_INMSGSRC1},
0093 {IDT_NT_INMSG2, IDT_NT_OUTMSG2, IDT_NT_INMSGSRC2},
0094 {IDT_NT_INMSG3, IDT_NT_OUTMSG3, IDT_NT_INMSGSRC3} }
0095 };
0096
0097
0098
0099
0100
0101 static const struct idt_ntb_port portdata_tbl[IDT_MAX_NR_PORTS] = {
0102 { IDT_SW_NTP0_PCIECMDSTS, IDT_SW_NTP0_PCIELCTLSTS,
0103 IDT_SW_NTP0_NTCTL,
0104 IDT_SW_SWPORT0CTL, IDT_SW_SWPORT0STS,
0105 { {IDT_SW_NTP0_BARSETUP0, IDT_SW_NTP0_BARLIMIT0,
0106 IDT_SW_NTP0_BARLTBASE0, IDT_SW_NTP0_BARUTBASE0},
0107 {IDT_SW_NTP0_BARSETUP1, IDT_SW_NTP0_BARLIMIT1,
0108 IDT_SW_NTP0_BARLTBASE1, IDT_SW_NTP0_BARUTBASE1},
0109 {IDT_SW_NTP0_BARSETUP2, IDT_SW_NTP0_BARLIMIT2,
0110 IDT_SW_NTP0_BARLTBASE2, IDT_SW_NTP0_BARUTBASE2},
0111 {IDT_SW_NTP0_BARSETUP3, IDT_SW_NTP0_BARLIMIT3,
0112 IDT_SW_NTP0_BARLTBASE3, IDT_SW_NTP0_BARUTBASE3},
0113 {IDT_SW_NTP0_BARSETUP4, IDT_SW_NTP0_BARLIMIT4,
0114 IDT_SW_NTP0_BARLTBASE4, IDT_SW_NTP0_BARUTBASE4},
0115 {IDT_SW_NTP0_BARSETUP5, IDT_SW_NTP0_BARLIMIT5,
0116 IDT_SW_NTP0_BARLTBASE5, IDT_SW_NTP0_BARUTBASE5} } },
0117 {0},
0118 { IDT_SW_NTP2_PCIECMDSTS, IDT_SW_NTP2_PCIELCTLSTS,
0119 IDT_SW_NTP2_NTCTL,
0120 IDT_SW_SWPORT2CTL, IDT_SW_SWPORT2STS,
0121 { {IDT_SW_NTP2_BARSETUP0, IDT_SW_NTP2_BARLIMIT0,
0122 IDT_SW_NTP2_BARLTBASE0, IDT_SW_NTP2_BARUTBASE0},
0123 {IDT_SW_NTP2_BARSETUP1, IDT_SW_NTP2_BARLIMIT1,
0124 IDT_SW_NTP2_BARLTBASE1, IDT_SW_NTP2_BARUTBASE1},
0125 {IDT_SW_NTP2_BARSETUP2, IDT_SW_NTP2_BARLIMIT2,
0126 IDT_SW_NTP2_BARLTBASE2, IDT_SW_NTP2_BARUTBASE2},
0127 {IDT_SW_NTP2_BARSETUP3, IDT_SW_NTP2_BARLIMIT3,
0128 IDT_SW_NTP2_BARLTBASE3, IDT_SW_NTP2_BARUTBASE3},
0129 {IDT_SW_NTP2_BARSETUP4, IDT_SW_NTP2_BARLIMIT4,
0130 IDT_SW_NTP2_BARLTBASE4, IDT_SW_NTP2_BARUTBASE4},
0131 {IDT_SW_NTP2_BARSETUP5, IDT_SW_NTP2_BARLIMIT5,
0132 IDT_SW_NTP2_BARLTBASE5, IDT_SW_NTP2_BARUTBASE5} } },
0133 {0},
0134 { IDT_SW_NTP4_PCIECMDSTS, IDT_SW_NTP4_PCIELCTLSTS,
0135 IDT_SW_NTP4_NTCTL,
0136 IDT_SW_SWPORT4CTL, IDT_SW_SWPORT4STS,
0137 { {IDT_SW_NTP4_BARSETUP0, IDT_SW_NTP4_BARLIMIT0,
0138 IDT_SW_NTP4_BARLTBASE0, IDT_SW_NTP4_BARUTBASE0},
0139 {IDT_SW_NTP4_BARSETUP1, IDT_SW_NTP4_BARLIMIT1,
0140 IDT_SW_NTP4_BARLTBASE1, IDT_SW_NTP4_BARUTBASE1},
0141 {IDT_SW_NTP4_BARSETUP2, IDT_SW_NTP4_BARLIMIT2,
0142 IDT_SW_NTP4_BARLTBASE2, IDT_SW_NTP4_BARUTBASE2},
0143 {IDT_SW_NTP4_BARSETUP3, IDT_SW_NTP4_BARLIMIT3,
0144 IDT_SW_NTP4_BARLTBASE3, IDT_SW_NTP4_BARUTBASE3},
0145 {IDT_SW_NTP4_BARSETUP4, IDT_SW_NTP4_BARLIMIT4,
0146 IDT_SW_NTP4_BARLTBASE4, IDT_SW_NTP4_BARUTBASE4},
0147 {IDT_SW_NTP4_BARSETUP5, IDT_SW_NTP4_BARLIMIT5,
0148 IDT_SW_NTP4_BARLTBASE5, IDT_SW_NTP4_BARUTBASE5} } },
0149 {0},
0150 { IDT_SW_NTP6_PCIECMDSTS, IDT_SW_NTP6_PCIELCTLSTS,
0151 IDT_SW_NTP6_NTCTL,
0152 IDT_SW_SWPORT6CTL, IDT_SW_SWPORT6STS,
0153 { {IDT_SW_NTP6_BARSETUP0, IDT_SW_NTP6_BARLIMIT0,
0154 IDT_SW_NTP6_BARLTBASE0, IDT_SW_NTP6_BARUTBASE0},
0155 {IDT_SW_NTP6_BARSETUP1, IDT_SW_NTP6_BARLIMIT1,
0156 IDT_SW_NTP6_BARLTBASE1, IDT_SW_NTP6_BARUTBASE1},
0157 {IDT_SW_NTP6_BARSETUP2, IDT_SW_NTP6_BARLIMIT2,
0158 IDT_SW_NTP6_BARLTBASE2, IDT_SW_NTP6_BARUTBASE2},
0159 {IDT_SW_NTP6_BARSETUP3, IDT_SW_NTP6_BARLIMIT3,
0160 IDT_SW_NTP6_BARLTBASE3, IDT_SW_NTP6_BARUTBASE3},
0161 {IDT_SW_NTP6_BARSETUP4, IDT_SW_NTP6_BARLIMIT4,
0162 IDT_SW_NTP6_BARLTBASE4, IDT_SW_NTP6_BARUTBASE4},
0163 {IDT_SW_NTP6_BARSETUP5, IDT_SW_NTP6_BARLIMIT5,
0164 IDT_SW_NTP6_BARLTBASE5, IDT_SW_NTP6_BARUTBASE5} } },
0165 {0},
0166 { IDT_SW_NTP8_PCIECMDSTS, IDT_SW_NTP8_PCIELCTLSTS,
0167 IDT_SW_NTP8_NTCTL,
0168 IDT_SW_SWPORT8CTL, IDT_SW_SWPORT8STS,
0169 { {IDT_SW_NTP8_BARSETUP0, IDT_SW_NTP8_BARLIMIT0,
0170 IDT_SW_NTP8_BARLTBASE0, IDT_SW_NTP8_BARUTBASE0},
0171 {IDT_SW_NTP8_BARSETUP1, IDT_SW_NTP8_BARLIMIT1,
0172 IDT_SW_NTP8_BARLTBASE1, IDT_SW_NTP8_BARUTBASE1},
0173 {IDT_SW_NTP8_BARSETUP2, IDT_SW_NTP8_BARLIMIT2,
0174 IDT_SW_NTP8_BARLTBASE2, IDT_SW_NTP8_BARUTBASE2},
0175 {IDT_SW_NTP8_BARSETUP3, IDT_SW_NTP8_BARLIMIT3,
0176 IDT_SW_NTP8_BARLTBASE3, IDT_SW_NTP8_BARUTBASE3},
0177 {IDT_SW_NTP8_BARSETUP4, IDT_SW_NTP8_BARLIMIT4,
0178 IDT_SW_NTP8_BARLTBASE4, IDT_SW_NTP8_BARUTBASE4},
0179 {IDT_SW_NTP8_BARSETUP5, IDT_SW_NTP8_BARLIMIT5,
0180 IDT_SW_NTP8_BARLTBASE5, IDT_SW_NTP8_BARUTBASE5} } },
0181 {0},
0182 {0},
0183 {0},
0184 { IDT_SW_NTP12_PCIECMDSTS, IDT_SW_NTP12_PCIELCTLSTS,
0185 IDT_SW_NTP12_NTCTL,
0186 IDT_SW_SWPORT12CTL, IDT_SW_SWPORT12STS,
0187 { {IDT_SW_NTP12_BARSETUP0, IDT_SW_NTP12_BARLIMIT0,
0188 IDT_SW_NTP12_BARLTBASE0, IDT_SW_NTP12_BARUTBASE0},
0189 {IDT_SW_NTP12_BARSETUP1, IDT_SW_NTP12_BARLIMIT1,
0190 IDT_SW_NTP12_BARLTBASE1, IDT_SW_NTP12_BARUTBASE1},
0191 {IDT_SW_NTP12_BARSETUP2, IDT_SW_NTP12_BARLIMIT2,
0192 IDT_SW_NTP12_BARLTBASE2, IDT_SW_NTP12_BARUTBASE2},
0193 {IDT_SW_NTP12_BARSETUP3, IDT_SW_NTP12_BARLIMIT3,
0194 IDT_SW_NTP12_BARLTBASE3, IDT_SW_NTP12_BARUTBASE3},
0195 {IDT_SW_NTP12_BARSETUP4, IDT_SW_NTP12_BARLIMIT4,
0196 IDT_SW_NTP12_BARLTBASE4, IDT_SW_NTP12_BARUTBASE4},
0197 {IDT_SW_NTP12_BARSETUP5, IDT_SW_NTP12_BARLIMIT5,
0198 IDT_SW_NTP12_BARLTBASE5, IDT_SW_NTP12_BARUTBASE5} } },
0199 {0},
0200 {0},
0201 {0},
0202 { IDT_SW_NTP16_PCIECMDSTS, IDT_SW_NTP16_PCIELCTLSTS,
0203 IDT_SW_NTP16_NTCTL,
0204 IDT_SW_SWPORT16CTL, IDT_SW_SWPORT16STS,
0205 { {IDT_SW_NTP16_BARSETUP0, IDT_SW_NTP16_BARLIMIT0,
0206 IDT_SW_NTP16_BARLTBASE0, IDT_SW_NTP16_BARUTBASE0},
0207 {IDT_SW_NTP16_BARSETUP1, IDT_SW_NTP16_BARLIMIT1,
0208 IDT_SW_NTP16_BARLTBASE1, IDT_SW_NTP16_BARUTBASE1},
0209 {IDT_SW_NTP16_BARSETUP2, IDT_SW_NTP16_BARLIMIT2,
0210 IDT_SW_NTP16_BARLTBASE2, IDT_SW_NTP16_BARUTBASE2},
0211 {IDT_SW_NTP16_BARSETUP3, IDT_SW_NTP16_BARLIMIT3,
0212 IDT_SW_NTP16_BARLTBASE3, IDT_SW_NTP16_BARUTBASE3},
0213 {IDT_SW_NTP16_BARSETUP4, IDT_SW_NTP16_BARLIMIT4,
0214 IDT_SW_NTP16_BARLTBASE4, IDT_SW_NTP16_BARUTBASE4},
0215 {IDT_SW_NTP16_BARSETUP5, IDT_SW_NTP16_BARLIMIT5,
0216 IDT_SW_NTP16_BARLTBASE5, IDT_SW_NTP16_BARUTBASE5} } },
0217 {0},
0218 {0},
0219 {0},
0220 { IDT_SW_NTP20_PCIECMDSTS, IDT_SW_NTP20_PCIELCTLSTS,
0221 IDT_SW_NTP20_NTCTL,
0222 IDT_SW_SWPORT20CTL, IDT_SW_SWPORT20STS,
0223 { {IDT_SW_NTP20_BARSETUP0, IDT_SW_NTP20_BARLIMIT0,
0224 IDT_SW_NTP20_BARLTBASE0, IDT_SW_NTP20_BARUTBASE0},
0225 {IDT_SW_NTP20_BARSETUP1, IDT_SW_NTP20_BARLIMIT1,
0226 IDT_SW_NTP20_BARLTBASE1, IDT_SW_NTP20_BARUTBASE1},
0227 {IDT_SW_NTP20_BARSETUP2, IDT_SW_NTP20_BARLIMIT2,
0228 IDT_SW_NTP20_BARLTBASE2, IDT_SW_NTP20_BARUTBASE2},
0229 {IDT_SW_NTP20_BARSETUP3, IDT_SW_NTP20_BARLIMIT3,
0230 IDT_SW_NTP20_BARLTBASE3, IDT_SW_NTP20_BARUTBASE3},
0231 {IDT_SW_NTP20_BARSETUP4, IDT_SW_NTP20_BARLIMIT4,
0232 IDT_SW_NTP20_BARLTBASE4, IDT_SW_NTP20_BARUTBASE4},
0233 {IDT_SW_NTP20_BARSETUP5, IDT_SW_NTP20_BARLIMIT5,
0234 IDT_SW_NTP20_BARLTBASE5, IDT_SW_NTP20_BARUTBASE5} } },
0235 {0},
0236 {0},
0237 {0}
0238 };
0239
0240
0241
0242
0243
0244 static const struct idt_ntb_part partdata_tbl[IDT_MAX_NR_PARTS] = {
0245 { IDT_SW_SWPART0CTL, IDT_SW_SWPART0STS,
0246 {IDT_SW_SWP0MSGCTL0, IDT_SW_SWP0MSGCTL1,
0247 IDT_SW_SWP0MSGCTL2, IDT_SW_SWP0MSGCTL3} },
0248 { IDT_SW_SWPART1CTL, IDT_SW_SWPART1STS,
0249 {IDT_SW_SWP1MSGCTL0, IDT_SW_SWP1MSGCTL1,
0250 IDT_SW_SWP1MSGCTL2, IDT_SW_SWP1MSGCTL3} },
0251 { IDT_SW_SWPART2CTL, IDT_SW_SWPART2STS,
0252 {IDT_SW_SWP2MSGCTL0, IDT_SW_SWP2MSGCTL1,
0253 IDT_SW_SWP2MSGCTL2, IDT_SW_SWP2MSGCTL3} },
0254 { IDT_SW_SWPART3CTL, IDT_SW_SWPART3STS,
0255 {IDT_SW_SWP3MSGCTL0, IDT_SW_SWP3MSGCTL1,
0256 IDT_SW_SWP3MSGCTL2, IDT_SW_SWP3MSGCTL3} },
0257 { IDT_SW_SWPART4CTL, IDT_SW_SWPART4STS,
0258 {IDT_SW_SWP4MSGCTL0, IDT_SW_SWP4MSGCTL1,
0259 IDT_SW_SWP4MSGCTL2, IDT_SW_SWP4MSGCTL3} },
0260 { IDT_SW_SWPART5CTL, IDT_SW_SWPART5STS,
0261 {IDT_SW_SWP5MSGCTL0, IDT_SW_SWP5MSGCTL1,
0262 IDT_SW_SWP5MSGCTL2, IDT_SW_SWP5MSGCTL3} },
0263 { IDT_SW_SWPART6CTL, IDT_SW_SWPART6STS,
0264 {IDT_SW_SWP6MSGCTL0, IDT_SW_SWP6MSGCTL1,
0265 IDT_SW_SWP6MSGCTL2, IDT_SW_SWP6MSGCTL3} },
0266 { IDT_SW_SWPART7CTL, IDT_SW_SWPART7STS,
0267 {IDT_SW_SWP7MSGCTL0, IDT_SW_SWP7MSGCTL1,
0268 IDT_SW_SWP7MSGCTL2, IDT_SW_SWP7MSGCTL3} }
0269 };
0270
0271
0272
0273
0274 static struct dentry *dbgfs_topdir;
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299 static void idt_nt_write(struct idt_ntb_dev *ndev,
0300 const unsigned int reg, const u32 data)
0301 {
0302
0303
0304
0305
0306 if (WARN_ON(reg > IDT_REG_PCI_MAX || !IS_ALIGNED(reg, IDT_REG_ALIGN)))
0307 return;
0308
0309
0310 iowrite32(data, ndev->cfgspc + (ptrdiff_t)reg);
0311 }
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322 static u32 idt_nt_read(struct idt_ntb_dev *ndev, const unsigned int reg)
0323 {
0324
0325
0326
0327
0328 if (WARN_ON(reg > IDT_REG_PCI_MAX || !IS_ALIGNED(reg, IDT_REG_ALIGN)))
0329 return ~0;
0330
0331
0332 return ioread32(ndev->cfgspc + (ptrdiff_t)reg);
0333 }
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343 static void idt_sw_write(struct idt_ntb_dev *ndev,
0344 const unsigned int reg, const u32 data)
0345 {
0346 unsigned long irqflags;
0347
0348
0349
0350
0351
0352 if (WARN_ON(reg > IDT_REG_SW_MAX || !IS_ALIGNED(reg, IDT_REG_ALIGN)))
0353 return;
0354
0355
0356 spin_lock_irqsave(&ndev->gasa_lock, irqflags);
0357
0358 iowrite32((u32)reg, ndev->cfgspc + (ptrdiff_t)IDT_NT_GASAADDR);
0359
0360 iowrite32(data, ndev->cfgspc + (ptrdiff_t)IDT_NT_GASADATA);
0361
0362 spin_unlock_irqrestore(&ndev->gasa_lock, irqflags);
0363 }
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374 static u32 idt_sw_read(struct idt_ntb_dev *ndev, const unsigned int reg)
0375 {
0376 unsigned long irqflags;
0377 u32 data;
0378
0379
0380
0381
0382
0383 if (WARN_ON(reg > IDT_REG_SW_MAX || !IS_ALIGNED(reg, IDT_REG_ALIGN)))
0384 return ~0;
0385
0386
0387 spin_lock_irqsave(&ndev->gasa_lock, irqflags);
0388
0389 iowrite32((u32)reg, ndev->cfgspc + (ptrdiff_t)IDT_NT_GASAADDR);
0390
0391 data = ioread32(ndev->cfgspc + (ptrdiff_t)IDT_NT_GASADATA);
0392
0393 spin_unlock_irqrestore(&ndev->gasa_lock, irqflags);
0394
0395 return data;
0396 }
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414 static inline int idt_reg_set_bits(struct idt_ntb_dev *ndev, unsigned int reg,
0415 spinlock_t *reg_lock,
0416 u64 valid_mask, u64 set_bits)
0417 {
0418 unsigned long irqflags;
0419 u32 data;
0420
0421 if (set_bits & ~(u64)valid_mask)
0422 return -EINVAL;
0423
0424
0425 spin_lock_irqsave(reg_lock, irqflags);
0426 data = idt_nt_read(ndev, reg) | (u32)set_bits;
0427 idt_nt_write(ndev, reg, data);
0428
0429 spin_unlock_irqrestore(reg_lock, irqflags);
0430
0431 return 0;
0432 }
0433
0434
0435
0436
0437
0438
0439
0440
0441
0442
0443
0444
0445
0446
0447
0448
0449
0450 static inline void idt_reg_clear_bits(struct idt_ntb_dev *ndev,
0451 unsigned int reg, spinlock_t *reg_lock,
0452 u64 clear_bits)
0453 {
0454 unsigned long irqflags;
0455 u32 data;
0456
0457
0458 spin_lock_irqsave(reg_lock, irqflags);
0459 data = idt_nt_read(ndev, reg) & ~(u32)clear_bits;
0460 idt_nt_write(ndev, reg, data);
0461
0462 spin_unlock_irqrestore(reg_lock, irqflags);
0463 }
0464
0465
0466
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480 static int idt_scan_ports(struct idt_ntb_dev *ndev)
0481 {
0482 unsigned char pidx, port, part;
0483 u32 data, portsts, partsts;
0484
0485
0486 data = idt_nt_read(ndev, IDT_NT_PCIELCAP);
0487 ndev->port = GET_FIELD(PCIELCAP_PORTNUM, data);
0488
0489
0490 portsts = idt_sw_read(ndev, portdata_tbl[ndev->port].sts);
0491 ndev->part = GET_FIELD(SWPORTxSTS_SWPART, portsts);
0492
0493
0494 memset(ndev->port_idx_map, -EINVAL, sizeof(ndev->port_idx_map));
0495 memset(ndev->part_idx_map, -EINVAL, sizeof(ndev->part_idx_map));
0496
0497
0498
0499
0500
0501 ndev->peer_cnt = 0;
0502 for (pidx = 0; pidx < ndev->swcfg->port_cnt; pidx++) {
0503 port = ndev->swcfg->ports[pidx];
0504
0505 if (port == ndev->port)
0506 continue;
0507
0508
0509 portsts = idt_sw_read(ndev, portdata_tbl[port].sts);
0510 part = GET_FIELD(SWPORTxSTS_SWPART, portsts);
0511
0512
0513 partsts = idt_sw_read(ndev, partdata_tbl[part].sts);
0514
0515 if (IS_FLD_SET(SWPARTxSTS_STATE, partsts, ACT) &&
0516 (IS_FLD_SET(SWPORTxSTS_MODE, portsts, NT) ||
0517 IS_FLD_SET(SWPORTxSTS_MODE, portsts, USNT) ||
0518 IS_FLD_SET(SWPORTxSTS_MODE, portsts, USNTDMA) ||
0519 IS_FLD_SET(SWPORTxSTS_MODE, portsts, NTDMA))) {
0520
0521 ndev->peers[ndev->peer_cnt].port = port;
0522 ndev->peers[ndev->peer_cnt].part = part;
0523
0524 ndev->port_idx_map[port] = ndev->peer_cnt;
0525 ndev->part_idx_map[part] = ndev->peer_cnt;
0526 ndev->peer_cnt++;
0527 }
0528 }
0529
0530 dev_dbg(&ndev->ntb.pdev->dev, "Local port: %hhu, num of peers: %hhu\n",
0531 ndev->port, ndev->peer_cnt);
0532
0533
0534 if (ndev->peer_cnt == 0) {
0535 dev_warn(&ndev->ntb.pdev->dev, "No active peer found\n");
0536 return -ENODEV;
0537 }
0538
0539 return 0;
0540 }
0541
0542
0543
0544
0545
0546
0547
0548 static int idt_ntb_port_number(struct ntb_dev *ntb)
0549 {
0550 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
0551
0552 return ndev->port;
0553 }
0554
0555
0556
0557
0558
0559
0560
0561
0562
0563 static int idt_ntb_peer_port_count(struct ntb_dev *ntb)
0564 {
0565 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
0566
0567 return ndev->peer_cnt;
0568 }
0569
0570
0571
0572
0573
0574
0575
0576
0577 static int idt_ntb_peer_port_number(struct ntb_dev *ntb, int pidx)
0578 {
0579 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
0580
0581 if (pidx < 0 || ndev->peer_cnt <= pidx)
0582 return -EINVAL;
0583
0584
0585 return ndev->peers[pidx].port;
0586 }
0587
0588
0589
0590
0591
0592
0593
0594
0595
0596
0597
0598 static int idt_ntb_peer_port_idx(struct ntb_dev *ntb, int port)
0599 {
0600 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
0601
0602 if (port < 0 || IDT_MAX_NR_PORTS <= port)
0603 return -EINVAL;
0604
0605 return ndev->port_idx_map[port];
0606 }
0607
0608
0609
0610
0611
0612
0613
0614
0615
0616
0617
0618
0619
0620
0621 static void idt_ntb_local_link_disable(struct idt_ntb_dev *ndev);
0622
0623
0624
0625
0626
0627
0628
0629
0630
0631
0632
0633
0634
0635 static void idt_init_link(struct idt_ntb_dev *ndev)
0636 {
0637 u32 part_mask, port_mask, se_mask;
0638 unsigned char pidx;
0639
0640
0641 spin_lock_init(&ndev->mtbl_lock);
0642
0643
0644 port_mask = ~BIT(ndev->port);
0645 part_mask = ~BIT(ndev->part);
0646 for (pidx = 0; pidx < ndev->peer_cnt; pidx++) {
0647 port_mask &= ~BIT(ndev->peers[pidx].port);
0648 part_mask &= ~BIT(ndev->peers[pidx].part);
0649 }
0650
0651
0652 idt_sw_write(ndev, IDT_SW_SELINKUPSTS, (u32)-1);
0653 idt_sw_write(ndev, IDT_SW_SELINKDNSTS, (u32)-1);
0654 idt_sw_write(ndev, IDT_SW_SEGSIGSTS, (u32)-1);
0655
0656
0657 idt_sw_write(ndev, IDT_SW_SEPMSK, part_mask);
0658
0659
0660 idt_sw_write(ndev, IDT_SW_SELINKUPMSK, port_mask);
0661
0662
0663 idt_sw_write(ndev, IDT_SW_SELINKDNMSK, port_mask);
0664
0665
0666 idt_sw_write(ndev, IDT_SW_SEGSIGMSK, part_mask);
0667
0668
0669 se_mask = ~(IDT_SEMSK_LINKUP | IDT_SEMSK_LINKDN | IDT_SEMSK_GSIGNAL);
0670 idt_sw_write(ndev, IDT_SW_SEMSK, se_mask);
0671
0672 dev_dbg(&ndev->ntb.pdev->dev, "NTB link status events initialized");
0673 }
0674
0675
0676
0677
0678
0679
0680
0681 static void idt_deinit_link(struct idt_ntb_dev *ndev)
0682 {
0683
0684 idt_ntb_local_link_disable(ndev);
0685
0686 dev_dbg(&ndev->ntb.pdev->dev, "NTB link status events deinitialized");
0687 }
0688
0689
0690
0691
0692
0693
0694
0695
0696
0697
0698
0699 static void idt_se_isr(struct idt_ntb_dev *ndev, u32 ntint_sts)
0700 {
0701 u32 sests;
0702
0703
0704 sests = idt_sw_read(ndev, IDT_SW_SESTS);
0705
0706
0707 idt_sw_write(ndev, IDT_SW_SELINKUPSTS, (u32)-1);
0708 idt_sw_write(ndev, IDT_SW_SELINKDNSTS, (u32)-1);
0709 idt_sw_write(ndev, IDT_SW_SEGSIGSTS, (u32)-1);
0710
0711
0712 idt_nt_write(ndev, IDT_NT_NTINTSTS, IDT_NTINTSTS_SEVENT);
0713
0714 dev_dbg(&ndev->ntb.pdev->dev, "SE IRQ detected %#08x (SESTS %#08x)",
0715 ntint_sts, sests);
0716
0717
0718 ntb_link_event(&ndev->ntb);
0719 }
0720
0721
0722
0723
0724
0725
0726
0727
0728
0729
0730 static void idt_ntb_local_link_enable(struct idt_ntb_dev *ndev)
0731 {
0732 u32 reqid, mtbldata = 0;
0733 unsigned long irqflags;
0734
0735
0736 idt_nt_write(ndev, IDT_NT_NTCTL, IDT_NTCTL_CPEN);
0737
0738
0739 reqid = idt_nt_read(ndev, IDT_NT_REQIDCAP);
0740
0741
0742
0743
0744
0745 mtbldata = SET_FIELD(NTMTBLDATA_REQID, 0, reqid) |
0746 SET_FIELD(NTMTBLDATA_PART, 0, ndev->part) |
0747 IDT_NTMTBLDATA_VALID;
0748 spin_lock_irqsave(&ndev->mtbl_lock, irqflags);
0749 idt_nt_write(ndev, IDT_NT_NTMTBLADDR, ndev->part);
0750 idt_nt_write(ndev, IDT_NT_NTMTBLDATA, mtbldata);
0751 spin_unlock_irqrestore(&ndev->mtbl_lock, irqflags);
0752
0753
0754 idt_nt_write(ndev, IDT_NT_NTGSIGNAL, IDT_NTGSIGNAL_SET);
0755 idt_sw_write(ndev, IDT_SW_SEGSIGSTS, (u32)1 << ndev->part);
0756 }
0757
0758
0759
0760
0761
0762
0763
0764
0765
0766
0767 static void idt_ntb_local_link_disable(struct idt_ntb_dev *ndev)
0768 {
0769 unsigned long irqflags;
0770
0771
0772 idt_nt_write(ndev, IDT_NT_NTCTL, 0);
0773
0774
0775 spin_lock_irqsave(&ndev->mtbl_lock, irqflags);
0776 idt_nt_write(ndev, IDT_NT_NTMTBLADDR, ndev->part);
0777 idt_nt_write(ndev, IDT_NT_NTMTBLDATA, 0);
0778 spin_unlock_irqrestore(&ndev->mtbl_lock, irqflags);
0779
0780
0781 idt_nt_write(ndev, IDT_NT_NTGSIGNAL, IDT_NTGSIGNAL_SET);
0782 idt_sw_write(ndev, IDT_SW_SEGSIGSTS, (u32)1 << ndev->part);
0783 }
0784
0785
0786
0787
0788
0789
0790
0791
0792
0793
0794
0795
0796
0797
0798 static bool idt_ntb_local_link_is_up(struct idt_ntb_dev *ndev)
0799 {
0800 unsigned long irqflags;
0801 u32 data;
0802
0803
0804 data = idt_nt_read(ndev, IDT_NT_PCICMDSTS);
0805 if (!(data & IDT_PCICMDSTS_BME))
0806 return false;
0807
0808
0809 data = idt_nt_read(ndev, IDT_NT_NTCTL);
0810 if (!(data & IDT_NTCTL_CPEN))
0811 return false;
0812
0813
0814 spin_lock_irqsave(&ndev->mtbl_lock, irqflags);
0815 idt_nt_write(ndev, IDT_NT_NTMTBLADDR, ndev->part);
0816 data = idt_nt_read(ndev, IDT_NT_NTMTBLDATA);
0817 spin_unlock_irqrestore(&ndev->mtbl_lock, irqflags);
0818
0819 return !!(data & IDT_NTMTBLDATA_VALID);
0820 }
0821
0822
0823
0824
0825
0826
0827
0828
0829
0830
0831
0832
0833
0834
0835 static bool idt_ntb_peer_link_is_up(struct idt_ntb_dev *ndev, int pidx)
0836 {
0837 unsigned long irqflags;
0838 unsigned char port;
0839 u32 data;
0840
0841
0842 port = ndev->peers[pidx].port;
0843
0844
0845 data = idt_sw_read(ndev, portdata_tbl[port].sts);
0846 if (!(data & IDT_SWPORTxSTS_LINKUP))
0847 return false;
0848
0849
0850 data = idt_sw_read(ndev, portdata_tbl[port].pcicmdsts);
0851 if (!(data & IDT_PCICMDSTS_BME))
0852 return false;
0853
0854
0855 data = idt_sw_read(ndev, portdata_tbl[port].ntctl);
0856 if (!(data & IDT_NTCTL_CPEN))
0857 return false;
0858
0859
0860 spin_lock_irqsave(&ndev->mtbl_lock, irqflags);
0861 idt_nt_write(ndev, IDT_NT_NTMTBLADDR, ndev->peers[pidx].part);
0862 data = idt_nt_read(ndev, IDT_NT_NTMTBLDATA);
0863 spin_unlock_irqrestore(&ndev->mtbl_lock, irqflags);
0864
0865 return !!(data & IDT_NTMTBLDATA_VALID);
0866 }
0867
0868
0869
0870
0871
0872
0873
0874
0875
0876
0877
0878
0879 static u64 idt_ntb_link_is_up(struct ntb_dev *ntb,
0880 enum ntb_speed *speed, enum ntb_width *width)
0881 {
0882 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
0883 unsigned char pidx;
0884 u64 status;
0885 u32 data;
0886
0887
0888 if (speed != NULL || width != NULL) {
0889 data = idt_nt_read(ndev, IDT_NT_PCIELCTLSTS);
0890 if (speed != NULL)
0891 *speed = GET_FIELD(PCIELCTLSTS_CLS, data);
0892 if (width != NULL)
0893 *width = GET_FIELD(PCIELCTLSTS_NLW, data);
0894 }
0895
0896
0897 if (!idt_ntb_local_link_is_up(ndev))
0898 return 0;
0899
0900
0901 status = 0;
0902 for (pidx = 0; pidx < ndev->peer_cnt; pidx++) {
0903 if (idt_ntb_peer_link_is_up(ndev, pidx))
0904 status |= ((u64)1 << pidx);
0905 }
0906
0907 return status;
0908 }
0909
0910
0911
0912
0913
0914
0915
0916
0917
0918
0919
0920 static int idt_ntb_link_enable(struct ntb_dev *ntb, enum ntb_speed speed,
0921 enum ntb_width width)
0922 {
0923 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
0924
0925
0926 idt_ntb_local_link_enable(ndev);
0927
0928 dev_dbg(&ndev->ntb.pdev->dev, "Local NTB link enabled");
0929
0930 return 0;
0931 }
0932
0933
0934
0935
0936
0937
0938
0939
0940
0941 static int idt_ntb_link_disable(struct ntb_dev *ntb)
0942 {
0943 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
0944
0945
0946 idt_ntb_local_link_disable(ndev);
0947
0948 dev_dbg(&ndev->ntb.pdev->dev, "Local NTB link disabled");
0949
0950 return 0;
0951 }
0952
0953
0954
0955
0956
0957
0958
0959
0960
0961
0962
0963
0964
0965
0966
0967
0968
0969
0970
0971
0972
0973
0974
0975
0976
0977
0978
0979
0980
0981
0982
0983
0984
0985
0986
0987
0988
0989
0990
0991
0992 static inline unsigned char idt_get_mw_count(enum idt_mw_type mw_type)
0993 {
0994 switch (mw_type) {
0995 case IDT_MW_DIR:
0996 return 1;
0997 case IDT_MW_LUT12:
0998 return 12;
0999 case IDT_MW_LUT24:
1000 return 24;
1001 default:
1002 break;
1003 }
1004
1005 return 0;
1006 }
1007
1008
1009
1010
1011
1012
1013
1014 static inline char *idt_get_mw_name(enum idt_mw_type mw_type)
1015 {
1016 switch (mw_type) {
1017 case IDT_MW_DIR:
1018 return "DIR ";
1019 case IDT_MW_LUT12:
1020 return "LUT12";
1021 case IDT_MW_LUT24:
1022 return "LUT24";
1023 default:
1024 break;
1025 }
1026
1027 return "unknown";
1028 }
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041 static struct idt_mw_cfg *idt_scan_mws(struct idt_ntb_dev *ndev, int port,
1042 unsigned char *mw_cnt)
1043 {
1044 struct idt_mw_cfg mws[IDT_MAX_NR_MWS], *ret_mws;
1045 const struct idt_ntb_bar *bars;
1046 enum idt_mw_type mw_type;
1047 unsigned char widx, bidx, en_cnt;
1048 bool bar_64bit = false;
1049 int aprt_size;
1050 u32 data;
1051
1052
1053 bars = portdata_tbl[port].bars;
1054
1055
1056 *mw_cnt = 0;
1057 for (bidx = 0; bidx < IDT_BAR_CNT; bidx += 1 + bar_64bit) {
1058
1059 data = idt_sw_read(ndev, bars[bidx].setup);
1060
1061
1062 if (!(data & IDT_BARSETUP_EN)) {
1063 bar_64bit = false;
1064 continue;
1065 }
1066
1067
1068 bar_64bit = IS_FLD_SET(BARSETUP_TYPE, data, 64);
1069
1070
1071 if (data & IDT_BARSETUP_MODE_CFG)
1072 continue;
1073
1074
1075 mw_type = GET_FIELD(BARSETUP_ATRAN, data);
1076 en_cnt = idt_get_mw_count(mw_type);
1077 aprt_size = (u64)1 << GET_FIELD(BARSETUP_SIZE, data);
1078
1079
1080 for (widx = 0; widx < en_cnt; widx++, (*mw_cnt)++) {
1081
1082
1083
1084
1085 if (*mw_cnt >= IDT_MAX_NR_MWS)
1086 return ERR_PTR(-EINVAL);
1087
1088
1089 mws[*mw_cnt].type = mw_type;
1090 mws[*mw_cnt].bar = bidx;
1091 mws[*mw_cnt].idx = widx;
1092
1093 mws[*mw_cnt].addr_align = IDT_TRANS_ALIGN;
1094
1095 if (mw_type == IDT_MW_DIR)
1096 mws[*mw_cnt].size_max = aprt_size;
1097 else if (mw_type == IDT_MW_LUT12)
1098 mws[*mw_cnt].size_max = aprt_size / 16;
1099 else
1100 mws[*mw_cnt].size_max = aprt_size / 32;
1101 mws[*mw_cnt].size_align = (mw_type == IDT_MW_DIR) ?
1102 IDT_DIR_SIZE_ALIGN : mws[*mw_cnt].size_max;
1103 }
1104 }
1105
1106
1107 ret_mws = devm_kcalloc(&ndev->ntb.pdev->dev, *mw_cnt, sizeof(*ret_mws),
1108 GFP_KERNEL);
1109 if (!ret_mws)
1110 return ERR_PTR(-ENOMEM);
1111
1112
1113 memcpy(ret_mws, mws, (*mw_cnt)*sizeof(*ret_mws));
1114
1115 return ret_mws;
1116 }
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127 static int idt_init_mws(struct idt_ntb_dev *ndev)
1128 {
1129 struct idt_ntb_peer *peer;
1130 unsigned char pidx;
1131
1132
1133 ndev->mws = idt_scan_mws(ndev, ndev->port, &ndev->mw_cnt);
1134 if (IS_ERR(ndev->mws)) {
1135 dev_err(&ndev->ntb.pdev->dev,
1136 "Failed to scan mws of local port %hhu", ndev->port);
1137 return PTR_ERR(ndev->mws);
1138 }
1139
1140
1141 for (pidx = 0; pidx < ndev->peer_cnt; pidx++) {
1142 peer = &ndev->peers[pidx];
1143 peer->mws = idt_scan_mws(ndev, peer->port, &peer->mw_cnt);
1144 if (IS_ERR(peer->mws)) {
1145 dev_err(&ndev->ntb.pdev->dev,
1146 "Failed to scan mws of port %hhu", peer->port);
1147 return PTR_ERR(peer->mws);
1148 }
1149 }
1150
1151
1152 spin_lock_init(&ndev->lut_lock);
1153
1154 dev_dbg(&ndev->ntb.pdev->dev, "Outbound and inbound MWs initialized");
1155
1156 return 0;
1157 }
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170 static int idt_ntb_mw_count(struct ntb_dev *ntb, int pidx)
1171 {
1172 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
1173
1174 if (pidx < 0 || ndev->peer_cnt <= pidx)
1175 return -EINVAL;
1176
1177 return ndev->peers[pidx].mw_cnt;
1178 }
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194 static int idt_ntb_mw_get_align(struct ntb_dev *ntb, int pidx, int widx,
1195 resource_size_t *addr_align,
1196 resource_size_t *size_align,
1197 resource_size_t *size_max)
1198 {
1199 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
1200 struct idt_ntb_peer *peer;
1201
1202 if (pidx < 0 || ndev->peer_cnt <= pidx)
1203 return -EINVAL;
1204
1205 peer = &ndev->peers[pidx];
1206
1207 if (widx < 0 || peer->mw_cnt <= widx)
1208 return -EINVAL;
1209
1210 if (addr_align != NULL)
1211 *addr_align = peer->mws[widx].addr_align;
1212
1213 if (size_align != NULL)
1214 *size_align = peer->mws[widx].size_align;
1215
1216 if (size_max != NULL)
1217 *size_max = peer->mws[widx].size_max;
1218
1219 return 0;
1220 }
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232 static int idt_ntb_peer_mw_count(struct ntb_dev *ntb)
1233 {
1234 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
1235
1236 return ndev->mw_cnt;
1237 }
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252 static int idt_ntb_peer_mw_get_addr(struct ntb_dev *ntb, int widx,
1253 phys_addr_t *base, resource_size_t *size)
1254 {
1255 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
1256
1257 if (widx < 0 || ndev->mw_cnt <= widx)
1258 return -EINVAL;
1259
1260
1261 if (base != NULL)
1262 *base = pci_resource_start(ntb->pdev, ndev->mws[widx].bar) +
1263 ndev->mws[widx].idx * ndev->mws[widx].size_max;
1264
1265
1266 if (size != NULL)
1267 *size = ndev->mws[widx].size_max;
1268
1269 return 0;
1270 }
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287 static int idt_ntb_peer_mw_set_trans(struct ntb_dev *ntb, int pidx, int widx,
1288 u64 addr, resource_size_t size)
1289 {
1290 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
1291 struct idt_mw_cfg *mw_cfg;
1292 u32 data = 0, lutoff = 0;
1293
1294 if (pidx < 0 || ndev->peer_cnt <= pidx)
1295 return -EINVAL;
1296
1297 if (widx < 0 || ndev->mw_cnt <= widx)
1298 return -EINVAL;
1299
1300
1301
1302
1303
1304 mw_cfg = &ndev->mws[widx];
1305 if (!IS_ALIGNED(addr, mw_cfg->addr_align))
1306 return -EINVAL;
1307 if (!IS_ALIGNED(size, mw_cfg->size_align) || size > mw_cfg->size_max)
1308 return -EINVAL;
1309
1310
1311 if (mw_cfg->type == IDT_MW_DIR) {
1312 const struct idt_ntb_bar *bar = &ntdata_tbl.bars[mw_cfg->bar];
1313 u64 limit;
1314
1315 data = idt_nt_read(ndev, bar->setup);
1316 data = SET_FIELD(BARSETUP_TPART, data, ndev->peers[pidx].part);
1317 idt_nt_write(ndev, bar->setup, data);
1318
1319 idt_nt_write(ndev, bar->ltbase, (u32)addr);
1320 idt_nt_write(ndev, bar->utbase, (u32)(addr >> 32));
1321
1322 limit = pci_bus_address(ntb->pdev, mw_cfg->bar) + size;
1323 idt_nt_write(ndev, bar->limit, (u32)limit);
1324 if (IS_FLD_SET(BARSETUP_TYPE, data, 64))
1325 idt_nt_write(ndev, (bar + 1)->limit, (limit >> 32));
1326 } else {
1327 unsigned long irqflags;
1328
1329 lutoff = SET_FIELD(LUTOFFSET_INDEX, 0, mw_cfg->idx) |
1330 SET_FIELD(LUTOFFSET_BAR, 0, mw_cfg->bar);
1331 data = SET_FIELD(LUTUDATA_PART, 0, ndev->peers[pidx].part) |
1332 IDT_LUTUDATA_VALID;
1333 spin_lock_irqsave(&ndev->lut_lock, irqflags);
1334 idt_nt_write(ndev, IDT_NT_LUTOFFSET, lutoff);
1335 idt_nt_write(ndev, IDT_NT_LUTLDATA, (u32)addr);
1336 idt_nt_write(ndev, IDT_NT_LUTMDATA, (u32)(addr >> 32));
1337 idt_nt_write(ndev, IDT_NT_LUTUDATA, data);
1338 spin_unlock_irqrestore(&ndev->lut_lock, irqflags);
1339
1340 }
1341
1342 return 0;
1343 }
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356 static int idt_ntb_peer_mw_clear_trans(struct ntb_dev *ntb, int pidx,
1357 int widx)
1358 {
1359 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
1360 struct idt_mw_cfg *mw_cfg;
1361
1362 if (pidx < 0 || ndev->peer_cnt <= pidx)
1363 return -EINVAL;
1364
1365 if (widx < 0 || ndev->mw_cnt <= widx)
1366 return -EINVAL;
1367
1368 mw_cfg = &ndev->mws[widx];
1369
1370
1371 if (mw_cfg->type == IDT_MW_DIR) {
1372 const struct idt_ntb_bar *bar = &ntdata_tbl.bars[mw_cfg->bar];
1373 u32 data;
1374
1375 data = idt_nt_read(ndev, bar->setup);
1376
1377 idt_nt_write(ndev, bar->limit, 0);
1378 if (IS_FLD_SET(BARSETUP_TYPE, data, 64))
1379 idt_nt_write(ndev, (bar + 1)->limit, 0);
1380 } else {
1381 unsigned long irqflags;
1382 u32 lutoff;
1383
1384 lutoff = SET_FIELD(LUTOFFSET_INDEX, 0, mw_cfg->idx) |
1385 SET_FIELD(LUTOFFSET_BAR, 0, mw_cfg->bar);
1386 spin_lock_irqsave(&ndev->lut_lock, irqflags);
1387 idt_nt_write(ndev, IDT_NT_LUTOFFSET, lutoff);
1388 idt_nt_write(ndev, IDT_NT_LUTLDATA, 0);
1389 idt_nt_write(ndev, IDT_NT_LUTMDATA, 0);
1390 idt_nt_write(ndev, IDT_NT_LUTUDATA, 0);
1391 spin_unlock_irqrestore(&ndev->lut_lock, irqflags);
1392 }
1393
1394 return 0;
1395 }
1396
1397
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 static void idt_db_isr(struct idt_ntb_dev *ndev, u32 ntint_sts)
1427 {
1428
1429
1430
1431
1432 dev_dbg(&ndev->ntb.pdev->dev, "DB IRQ detected %#08x", ntint_sts);
1433
1434
1435 ntb_db_event(&ndev->ntb, 0);
1436 }
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447 static u64 idt_ntb_db_valid_mask(struct ntb_dev *ntb)
1448 {
1449 return IDT_DBELL_MASK;
1450 }
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461 static u64 idt_ntb_db_read(struct ntb_dev *ntb)
1462 {
1463 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
1464
1465 return idt_nt_read(ndev, IDT_NT_INDBELLSTS);
1466 }
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481 static int idt_ntb_db_clear(struct ntb_dev *ntb, u64 db_bits)
1482 {
1483 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
1484
1485 idt_nt_write(ndev, IDT_NT_INDBELLSTS, (u32)db_bits);
1486
1487 return 0;
1488 }
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500 static u64 idt_ntb_db_read_mask(struct ntb_dev *ntb)
1501 {
1502 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
1503
1504 return idt_nt_read(ndev, IDT_NT_INDBELLMSK);
1505 }
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518 static int idt_ntb_db_set_mask(struct ntb_dev *ntb, u64 db_bits)
1519 {
1520 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
1521
1522 return idt_reg_set_bits(ndev, IDT_NT_INDBELLMSK, &ndev->db_mask_lock,
1523 IDT_DBELL_MASK, db_bits);
1524 }
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539 static int idt_ntb_db_clear_mask(struct ntb_dev *ntb, u64 db_bits)
1540 {
1541 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
1542
1543 idt_reg_clear_bits(ndev, IDT_NT_INDBELLMSK, &ndev->db_mask_lock,
1544 db_bits);
1545
1546 return 0;
1547 }
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560 static int idt_ntb_peer_db_set(struct ntb_dev *ntb, u64 db_bits)
1561 {
1562 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
1563
1564 if (db_bits & ~(u64)IDT_DBELL_MASK)
1565 return -EINVAL;
1566
1567 idt_nt_write(ndev, IDT_NT_OUTDBELLSET, (u32)db_bits);
1568 return 0;
1569 }
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588 static void idt_init_msg(struct idt_ntb_dev *ndev)
1589 {
1590 unsigned char midx;
1591
1592
1593 for (midx = 0; midx < IDT_MSG_CNT; midx++)
1594 spin_lock_init(&ndev->msg_locks[midx]);
1595
1596 dev_dbg(&ndev->ntb.pdev->dev, "NTB Messaging initialized");
1597 }
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609 static void idt_msg_isr(struct idt_ntb_dev *ndev, u32 ntint_sts)
1610 {
1611
1612
1613
1614
1615 dev_dbg(&ndev->ntb.pdev->dev, "Message IRQ detected %#08x", ntint_sts);
1616
1617
1618 ntb_msg_event(&ndev->ntb);
1619 }
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629 static int idt_ntb_msg_count(struct ntb_dev *ntb)
1630 {
1631 return IDT_MSG_CNT;
1632 }
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644 static u64 idt_ntb_msg_inbits(struct ntb_dev *ntb)
1645 {
1646 return (u64)IDT_INMSG_MASK;
1647 }
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659 static u64 idt_ntb_msg_outbits(struct ntb_dev *ntb)
1660 {
1661 return (u64)IDT_OUTMSG_MASK;
1662 }
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673 static u64 idt_ntb_msg_read_sts(struct ntb_dev *ntb)
1674 {
1675 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
1676
1677 return idt_nt_read(ndev, IDT_NT_MSGSTS);
1678 }
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693 static int idt_ntb_msg_clear_sts(struct ntb_dev *ntb, u64 sts_bits)
1694 {
1695 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
1696
1697 idt_nt_write(ndev, IDT_NT_MSGSTS, sts_bits);
1698
1699 return 0;
1700 }
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712 static int idt_ntb_msg_set_mask(struct ntb_dev *ntb, u64 mask_bits)
1713 {
1714 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
1715
1716 return idt_reg_set_bits(ndev, IDT_NT_MSGSTSMSK, &ndev->msg_mask_lock,
1717 IDT_MSG_MASK, mask_bits);
1718 }
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730 static int idt_ntb_msg_clear_mask(struct ntb_dev *ntb, u64 mask_bits)
1731 {
1732 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
1733
1734 idt_reg_clear_bits(ndev, IDT_NT_MSGSTSMSK, &ndev->msg_mask_lock,
1735 mask_bits);
1736
1737 return 0;
1738 }
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751 static u32 idt_ntb_msg_read(struct ntb_dev *ntb, int *pidx, int midx)
1752 {
1753 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
1754
1755 if (midx < 0 || IDT_MSG_CNT <= midx)
1756 return ~(u32)0;
1757
1758
1759 if (pidx != NULL) {
1760 u32 srcpart;
1761
1762 srcpart = idt_nt_read(ndev, ntdata_tbl.msgs[midx].src);
1763 *pidx = ndev->part_idx_map[srcpart];
1764
1765
1766 if (*pidx == -EINVAL)
1767 *pidx = 0;
1768 }
1769
1770
1771 return idt_nt_read(ndev, ntdata_tbl.msgs[midx].in);
1772 }
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787 static int idt_ntb_peer_msg_write(struct ntb_dev *ntb, int pidx, int midx,
1788 u32 msg)
1789 {
1790 struct idt_ntb_dev *ndev = to_ndev_ntb(ntb);
1791 unsigned long irqflags;
1792 u32 swpmsgctl = 0;
1793
1794 if (midx < 0 || IDT_MSG_CNT <= midx)
1795 return -EINVAL;
1796
1797 if (pidx < 0 || ndev->peer_cnt <= pidx)
1798 return -EINVAL;
1799
1800
1801 swpmsgctl = SET_FIELD(SWPxMSGCTL_REG, 0, midx) |
1802 SET_FIELD(SWPxMSGCTL_PART, 0, ndev->peers[pidx].part);
1803
1804
1805 spin_lock_irqsave(&ndev->msg_locks[midx], irqflags);
1806
1807 idt_sw_write(ndev, partdata_tbl[ndev->part].msgctl[midx], swpmsgctl);
1808 idt_nt_write(ndev, ntdata_tbl.msgs[midx].out, msg);
1809
1810 spin_unlock_irqrestore(&ndev->msg_locks[midx], irqflags);
1811
1812
1813 return 0;
1814 }
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834 static inline s8 idt_get_deg(long mdegC)
1835 {
1836 return mdegC / 1000;
1837 }
1838
1839
1840
1841
1842
1843
1844
1845 static inline u8 idt_get_deg_frac(long mdegC)
1846 {
1847 return (mdegC % 1000) >= 500 ? 5 : 0;
1848 }
1849
1850
1851
1852
1853
1854
1855
1856 static inline u8 idt_temp_get_fmt(long mdegC)
1857 {
1858 return (idt_get_deg(mdegC) << 1) | (idt_get_deg_frac(mdegC) ? 1 : 0);
1859 }
1860
1861
1862
1863
1864
1865
1866
1867 static inline long idt_get_temp_sval(u32 data)
1868 {
1869 return ((s8)data / 2) * 1000 + (data & 0x1 ? 500 : 0);
1870 }
1871
1872
1873
1874
1875
1876
1877
1878 static inline long idt_get_temp_uval(u32 data)
1879 {
1880 return (data / 2) * 1000 + (data & 0x1 ? 500 : 0);
1881 }
1882
1883
1884
1885
1886
1887
1888
1889 static void idt_read_temp(struct idt_ntb_dev *ndev,
1890 const enum idt_temp_val type, long *val)
1891 {
1892 u32 data;
1893
1894
1895 switch (type) {
1896 case IDT_TEMP_CUR:
1897 data = GET_FIELD(TMPSTS_TEMP,
1898 idt_sw_read(ndev, IDT_SW_TMPSTS));
1899 break;
1900 case IDT_TEMP_LOW:
1901 data = GET_FIELD(TMPSTS_LTEMP,
1902 idt_sw_read(ndev, IDT_SW_TMPSTS));
1903 break;
1904 case IDT_TEMP_HIGH:
1905 data = GET_FIELD(TMPSTS_HTEMP,
1906 idt_sw_read(ndev, IDT_SW_TMPSTS));
1907 break;
1908 case IDT_TEMP_OFFSET:
1909
1910 data = GET_FIELD(TMPADJ_OFFSET,
1911 idt_sw_read(ndev, IDT_SW_TMPADJ));
1912 *val = idt_get_temp_sval(data);
1913 return;
1914 default:
1915 data = GET_FIELD(TMPSTS_TEMP,
1916 idt_sw_read(ndev, IDT_SW_TMPSTS));
1917 break;
1918 }
1919
1920
1921 *val = idt_get_temp_uval(data);
1922 }
1923
1924
1925
1926
1927
1928
1929
1930 static void idt_write_temp(struct idt_ntb_dev *ndev,
1931 const enum idt_temp_val type, const long val)
1932 {
1933 unsigned int reg;
1934 u32 data;
1935 u8 fmt;
1936
1937
1938 fmt = idt_temp_get_fmt(val);
1939
1940 mutex_lock(&ndev->hwmon_mtx);
1941 switch (type) {
1942 case IDT_TEMP_LOW:
1943 reg = IDT_SW_TMPALARM;
1944 data = SET_FIELD(TMPALARM_LTEMP, idt_sw_read(ndev, reg), fmt) &
1945 ~IDT_TMPALARM_IRQ_MASK;
1946 break;
1947 case IDT_TEMP_HIGH:
1948 reg = IDT_SW_TMPALARM;
1949 data = SET_FIELD(TMPALARM_HTEMP, idt_sw_read(ndev, reg), fmt) &
1950 ~IDT_TMPALARM_IRQ_MASK;
1951 break;
1952 case IDT_TEMP_OFFSET:
1953 reg = IDT_SW_TMPADJ;
1954 data = SET_FIELD(TMPADJ_OFFSET, idt_sw_read(ndev, reg), fmt);
1955 break;
1956 default:
1957 goto inval_spin_unlock;
1958 }
1959
1960 idt_sw_write(ndev, reg, data);
1961
1962 inval_spin_unlock:
1963 mutex_unlock(&ndev->hwmon_mtx);
1964 }
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974 static ssize_t idt_sysfs_show_temp(struct device *dev,
1975 struct device_attribute *da, char *buf)
1976 {
1977 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
1978 struct idt_ntb_dev *ndev = dev_get_drvdata(dev);
1979 enum idt_temp_val type = attr->index;
1980 long mdeg;
1981
1982 idt_read_temp(ndev, type, &mdeg);
1983 return sprintf(buf, "%ld\n", mdeg);
1984 }
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995 static ssize_t idt_sysfs_set_temp(struct device *dev,
1996 struct device_attribute *da, const char *buf,
1997 size_t count)
1998 {
1999 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
2000 struct idt_ntb_dev *ndev = dev_get_drvdata(dev);
2001 enum idt_temp_val type = attr->index;
2002 long mdeg;
2003 int ret;
2004
2005 ret = kstrtol(buf, 10, &mdeg);
2006 if (ret)
2007 return ret;
2008
2009
2010 if (type == IDT_TEMP_OFFSET)
2011 mdeg = clamp_val(mdeg, IDT_TEMP_MIN_OFFSET,
2012 IDT_TEMP_MAX_OFFSET);
2013 else
2014 mdeg = clamp_val(mdeg, IDT_TEMP_MIN_MDEG, IDT_TEMP_MAX_MDEG);
2015
2016 idt_write_temp(ndev, type, mdeg);
2017
2018 return count;
2019 }
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030 static ssize_t idt_sysfs_reset_hist(struct device *dev,
2031 struct device_attribute *da,
2032 const char *buf, size_t count)
2033 {
2034 struct idt_ntb_dev *ndev = dev_get_drvdata(dev);
2035
2036
2037
2038
2039 idt_write_temp(ndev, IDT_TEMP_LOW, IDT_TEMP_MAX_MDEG);
2040 idt_write_temp(ndev, IDT_TEMP_HIGH, IDT_TEMP_MIN_MDEG);
2041
2042 return count;
2043 }
2044
2045
2046
2047
2048 static SENSOR_DEVICE_ATTR(temp1_input, 0444, idt_sysfs_show_temp, NULL,
2049 IDT_TEMP_CUR);
2050 static SENSOR_DEVICE_ATTR(temp1_lowest, 0444, idt_sysfs_show_temp, NULL,
2051 IDT_TEMP_LOW);
2052 static SENSOR_DEVICE_ATTR(temp1_highest, 0444, idt_sysfs_show_temp, NULL,
2053 IDT_TEMP_HIGH);
2054 static SENSOR_DEVICE_ATTR(temp1_offset, 0644, idt_sysfs_show_temp,
2055 idt_sysfs_set_temp, IDT_TEMP_OFFSET);
2056 static DEVICE_ATTR(temp1_reset_history, 0200, NULL, idt_sysfs_reset_hist);
2057
2058
2059
2060
2061 static struct attribute *idt_temp_attrs[] = {
2062 &sensor_dev_attr_temp1_input.dev_attr.attr,
2063 &sensor_dev_attr_temp1_lowest.dev_attr.attr,
2064 &sensor_dev_attr_temp1_highest.dev_attr.attr,
2065 &sensor_dev_attr_temp1_offset.dev_attr.attr,
2066 &dev_attr_temp1_reset_history.attr,
2067 NULL
2068 };
2069 ATTRIBUTE_GROUPS(idt_temp);
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080 static void idt_init_temp(struct idt_ntb_dev *ndev)
2081 {
2082 struct device *hwmon;
2083
2084
2085 idt_sw_write(ndev, IDT_SW_TMPCTL, 0x0);
2086
2087
2088 mutex_init(&ndev->hwmon_mtx);
2089
2090 hwmon = devm_hwmon_device_register_with_groups(&ndev->ntb.pdev->dev,
2091 ndev->swcfg->name, ndev, idt_temp_groups);
2092 if (IS_ERR(hwmon)) {
2093 dev_err(&ndev->ntb.pdev->dev, "Couldn't create hwmon device");
2094 return;
2095 }
2096
2097 dev_dbg(&ndev->ntb.pdev->dev, "Temperature HWmon interface registered");
2098 }
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117 static irqreturn_t idt_thread_isr(int irq, void *devid);
2118
2119
2120
2121
2122
2123
2124
2125 static int idt_init_isr(struct idt_ntb_dev *ndev)
2126 {
2127 struct pci_dev *pdev = ndev->ntb.pdev;
2128 u32 ntint_mask;
2129 int ret;
2130
2131
2132 ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI | PCI_IRQ_LEGACY);
2133 if (ret != 1) {
2134 dev_err(&pdev->dev, "Failed to allocate IRQ vector");
2135 return ret;
2136 }
2137
2138
2139 ret = pci_irq_vector(pdev, 0);
2140 if (ret < 0) {
2141 dev_err(&pdev->dev, "Failed to get IRQ vector");
2142 goto err_free_vectors;
2143 }
2144
2145
2146 ret = devm_request_threaded_irq(&pdev->dev, ret, NULL, idt_thread_isr,
2147 IRQF_ONESHOT, NTB_IRQNAME, ndev);
2148 if (ret != 0) {
2149 dev_err(&pdev->dev, "Failed to set MSI IRQ handler, %d", ret);
2150 goto err_free_vectors;
2151 }
2152
2153
2154 ntint_mask = idt_nt_read(ndev, IDT_NT_NTINTMSK) & ~IDT_NTINTMSK_ALL;
2155 idt_nt_write(ndev, IDT_NT_NTINTMSK, ntint_mask);
2156
2157
2158 dev_dbg(&pdev->dev, "NTB interrupts initialized");
2159
2160 return 0;
2161
2162 err_free_vectors:
2163 pci_free_irq_vectors(pdev);
2164
2165 return ret;
2166 }
2167
2168
2169
2170
2171
2172
2173
2174 static void idt_deinit_isr(struct idt_ntb_dev *ndev)
2175 {
2176 struct pci_dev *pdev = ndev->ntb.pdev;
2177 u32 ntint_mask;
2178
2179
2180 ntint_mask = idt_nt_read(ndev, IDT_NT_NTINTMSK) | IDT_NTINTMSK_ALL;
2181 idt_nt_write(ndev, IDT_NT_NTINTMSK, ntint_mask);
2182
2183
2184 devm_free_irq(&pdev->dev, pci_irq_vector(pdev, 0), ndev);
2185
2186
2187 pci_free_irq_vectors(pdev);
2188
2189 dev_dbg(&pdev->dev, "NTB interrupts deinitialized");
2190 }
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201 static irqreturn_t idt_thread_isr(int irq, void *devid)
2202 {
2203 struct idt_ntb_dev *ndev = devid;
2204 bool handled = false;
2205 u32 ntint_sts;
2206
2207
2208 ntint_sts = idt_nt_read(ndev, IDT_NT_NTINTSTS);
2209
2210
2211 if (ntint_sts & IDT_NTINTSTS_MSG) {
2212 idt_msg_isr(ndev, ntint_sts);
2213 handled = true;
2214 }
2215
2216
2217 if (ntint_sts & IDT_NTINTSTS_DBELL) {
2218 idt_db_isr(ndev, ntint_sts);
2219 handled = true;
2220 }
2221
2222
2223 if (ntint_sts & IDT_NTINTSTS_SEVENT) {
2224 idt_se_isr(ndev, ntint_sts);
2225 handled = true;
2226 }
2227
2228 dev_dbg(&ndev->ntb.pdev->dev, "IDT IRQs 0x%08x handled", ntint_sts);
2229
2230 return handled ? IRQ_HANDLED : IRQ_NONE;
2231 }
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241 static const struct ntb_dev_ops idt_ntb_ops = {
2242 .port_number = idt_ntb_port_number,
2243 .peer_port_count = idt_ntb_peer_port_count,
2244 .peer_port_number = idt_ntb_peer_port_number,
2245 .peer_port_idx = idt_ntb_peer_port_idx,
2246 .link_is_up = idt_ntb_link_is_up,
2247 .link_enable = idt_ntb_link_enable,
2248 .link_disable = idt_ntb_link_disable,
2249 .mw_count = idt_ntb_mw_count,
2250 .mw_get_align = idt_ntb_mw_get_align,
2251 .peer_mw_count = idt_ntb_peer_mw_count,
2252 .peer_mw_get_addr = idt_ntb_peer_mw_get_addr,
2253 .peer_mw_set_trans = idt_ntb_peer_mw_set_trans,
2254 .peer_mw_clear_trans = idt_ntb_peer_mw_clear_trans,
2255 .db_valid_mask = idt_ntb_db_valid_mask,
2256 .db_read = idt_ntb_db_read,
2257 .db_clear = idt_ntb_db_clear,
2258 .db_read_mask = idt_ntb_db_read_mask,
2259 .db_set_mask = idt_ntb_db_set_mask,
2260 .db_clear_mask = idt_ntb_db_clear_mask,
2261 .peer_db_set = idt_ntb_peer_db_set,
2262 .msg_count = idt_ntb_msg_count,
2263 .msg_inbits = idt_ntb_msg_inbits,
2264 .msg_outbits = idt_ntb_msg_outbits,
2265 .msg_read_sts = idt_ntb_msg_read_sts,
2266 .msg_clear_sts = idt_ntb_msg_clear_sts,
2267 .msg_set_mask = idt_ntb_msg_set_mask,
2268 .msg_clear_mask = idt_ntb_msg_clear_mask,
2269 .msg_read = idt_ntb_msg_read,
2270 .peer_msg_write = idt_ntb_peer_msg_write
2271 };
2272
2273
2274
2275
2276
2277
2278
2279 static int idt_register_device(struct idt_ntb_dev *ndev)
2280 {
2281 int ret;
2282
2283
2284 ndev->ntb.ops = &idt_ntb_ops;
2285 ndev->ntb.topo = NTB_TOPO_SWITCH;
2286
2287 ret = ntb_register_device(&ndev->ntb);
2288 if (ret != 0) {
2289 dev_err(&ndev->ntb.pdev->dev, "Failed to register NTB device");
2290 return ret;
2291 }
2292
2293 dev_dbg(&ndev->ntb.pdev->dev, "NTB device successfully registered");
2294
2295 return 0;
2296 }
2297
2298
2299
2300
2301
2302 static void idt_unregister_device(struct idt_ntb_dev *ndev)
2303 {
2304
2305 ntb_unregister_device(&ndev->ntb);
2306
2307 dev_dbg(&ndev->ntb.pdev->dev, "NTB device unregistered");
2308 }
2309
2310
2311
2312
2313
2314
2315 static ssize_t idt_dbgfs_info_read(struct file *filp, char __user *ubuf,
2316 size_t count, loff_t *offp);
2317
2318
2319
2320
2321 static const struct file_operations idt_dbgfs_info_ops = {
2322 .owner = THIS_MODULE,
2323 .open = simple_open,
2324 .read = idt_dbgfs_info_read
2325 };
2326
2327
2328
2329
2330
2331
2332
2333
2334 static ssize_t idt_dbgfs_info_read(struct file *filp, char __user *ubuf,
2335 size_t count, loff_t *offp)
2336 {
2337 struct idt_ntb_dev *ndev = filp->private_data;
2338 unsigned char idx, pidx, cnt;
2339 unsigned long irqflags, mdeg;
2340 ssize_t ret = 0, off = 0;
2341 enum ntb_speed speed;
2342 enum ntb_width width;
2343 char *strbuf;
2344 size_t size;
2345 u32 data;
2346
2347
2348 size = min_t(size_t, count, 0x1000U);
2349
2350
2351 strbuf = kmalloc(size, GFP_KERNEL);
2352 if (strbuf == NULL)
2353 return -ENOMEM;
2354
2355
2356 off += scnprintf(strbuf + off, size - off,
2357 "\n\t\tIDT NTB device Information:\n\n");
2358
2359
2360 off += scnprintf(strbuf + off, size - off,
2361 "Local Port %hhu, Partition %hhu\n", ndev->port, ndev->part);
2362
2363
2364 off += scnprintf(strbuf + off, size - off, "Peers:\n");
2365 for (idx = 0; idx < ndev->peer_cnt; idx++) {
2366 off += scnprintf(strbuf + off, size - off,
2367 "\t%hhu. Port %hhu, Partition %hhu\n",
2368 idx, ndev->peers[idx].port, ndev->peers[idx].part);
2369 }
2370
2371
2372 data = idt_ntb_link_is_up(&ndev->ntb, &speed, &width);
2373 off += scnprintf(strbuf + off, size - off,
2374 "NTB link status\t- 0x%08x, ", data);
2375 off += scnprintf(strbuf + off, size - off, "PCIe Gen %d x%d lanes\n",
2376 speed, width);
2377
2378
2379 off += scnprintf(strbuf + off, size - off, "NTB Mapping Table:\n");
2380 for (idx = 0; idx < IDT_MTBL_ENTRY_CNT; idx++) {
2381 spin_lock_irqsave(&ndev->mtbl_lock, irqflags);
2382 idt_nt_write(ndev, IDT_NT_NTMTBLADDR, idx);
2383 data = idt_nt_read(ndev, IDT_NT_NTMTBLDATA);
2384 spin_unlock_irqrestore(&ndev->mtbl_lock, irqflags);
2385
2386
2387 if (data & IDT_NTMTBLDATA_VALID) {
2388 off += scnprintf(strbuf + off, size - off,
2389 "\t%hhu. Partition %d, Requester ID 0x%04x\n",
2390 idx, GET_FIELD(NTMTBLDATA_PART, data),
2391 GET_FIELD(NTMTBLDATA_REQID, data));
2392 }
2393 }
2394 off += scnprintf(strbuf + off, size - off, "\n");
2395
2396
2397 off += scnprintf(strbuf + off, size - off,
2398 "Outbound Memory Windows:\n");
2399 for (idx = 0; idx < ndev->mw_cnt; idx += cnt) {
2400 data = ndev->mws[idx].type;
2401 cnt = idt_get_mw_count(data);
2402
2403
2404 if (data == IDT_MW_DIR)
2405 off += scnprintf(strbuf + off, size - off,
2406 "\t%hhu.\t", idx);
2407 else
2408 off += scnprintf(strbuf + off, size - off,
2409 "\t%hhu-%d.\t", idx, idx + cnt - 1);
2410
2411 off += scnprintf(strbuf + off, size - off, "%s BAR%hhu, ",
2412 idt_get_mw_name(data), ndev->mws[idx].bar);
2413
2414 off += scnprintf(strbuf + off, size - off,
2415 "Address align 0x%08llx, ", ndev->mws[idx].addr_align);
2416
2417 off += scnprintf(strbuf + off, size - off,
2418 "Size align 0x%08llx, Size max %llu\n",
2419 ndev->mws[idx].size_align, ndev->mws[idx].size_max);
2420 }
2421
2422
2423 for (pidx = 0; pidx < ndev->peer_cnt; pidx++) {
2424 off += scnprintf(strbuf + off, size - off,
2425 "Inbound Memory Windows for peer %hhu (Port %hhu):\n",
2426 pidx, ndev->peers[pidx].port);
2427
2428
2429 for (idx = 0; idx < ndev->peers[pidx].mw_cnt; idx += cnt) {
2430 data = ndev->peers[pidx].mws[idx].type;
2431 cnt = idt_get_mw_count(data);
2432
2433 if (data == IDT_MW_DIR)
2434 off += scnprintf(strbuf + off, size - off,
2435 "\t%hhu.\t", idx);
2436 else
2437 off += scnprintf(strbuf + off, size - off,
2438 "\t%hhu-%d.\t", idx, idx + cnt - 1);
2439
2440 off += scnprintf(strbuf + off, size - off,
2441 "%s BAR%hhu, ", idt_get_mw_name(data),
2442 ndev->peers[pidx].mws[idx].bar);
2443
2444 off += scnprintf(strbuf + off, size - off,
2445 "Address align 0x%08llx, ",
2446 ndev->peers[pidx].mws[idx].addr_align);
2447
2448 off += scnprintf(strbuf + off, size - off,
2449 "Size align 0x%08llx, Size max %llu\n",
2450 ndev->peers[pidx].mws[idx].size_align,
2451 ndev->peers[pidx].mws[idx].size_max);
2452 }
2453 }
2454 off += scnprintf(strbuf + off, size - off, "\n");
2455
2456
2457 data = idt_sw_read(ndev, IDT_SW_GDBELLSTS);
2458 off += scnprintf(strbuf + off, size - off,
2459 "Global Doorbell state\t- 0x%08x\n", data);
2460 data = idt_ntb_db_read(&ndev->ntb);
2461 off += scnprintf(strbuf + off, size - off,
2462 "Local Doorbell state\t- 0x%08x\n", data);
2463 data = idt_nt_read(ndev, IDT_NT_INDBELLMSK);
2464 off += scnprintf(strbuf + off, size - off,
2465 "Local Doorbell mask\t- 0x%08x\n", data);
2466 off += scnprintf(strbuf + off, size - off, "\n");
2467
2468
2469 off += scnprintf(strbuf + off, size - off,
2470 "Message event valid\t- 0x%08x\n", IDT_MSG_MASK);
2471 data = idt_ntb_msg_read_sts(&ndev->ntb);
2472 off += scnprintf(strbuf + off, size - off,
2473 "Message event status\t- 0x%08x\n", data);
2474 data = idt_nt_read(ndev, IDT_NT_MSGSTSMSK);
2475 off += scnprintf(strbuf + off, size - off,
2476 "Message event mask\t- 0x%08x\n", data);
2477 off += scnprintf(strbuf + off, size - off,
2478 "Message data:\n");
2479 for (idx = 0; idx < IDT_MSG_CNT; idx++) {
2480 int src;
2481 data = idt_ntb_msg_read(&ndev->ntb, &src, idx);
2482 off += scnprintf(strbuf + off, size - off,
2483 "\t%hhu. 0x%08x from peer %d (Port %hhu)\n",
2484 idx, data, src, ndev->peers[src].port);
2485 }
2486 off += scnprintf(strbuf + off, size - off, "\n");
2487
2488
2489 idt_read_temp(ndev, IDT_TEMP_CUR, &mdeg);
2490 off += scnprintf(strbuf + off, size - off,
2491 "Switch temperature\t\t- %hhd.%hhuC\n",
2492 idt_get_deg(mdeg), idt_get_deg_frac(mdeg));
2493
2494
2495 ret = simple_read_from_buffer(ubuf, count, offp, strbuf, off);
2496 kfree(strbuf);
2497
2498 return ret;
2499 }
2500
2501
2502
2503
2504
2505
2506
2507 static int idt_init_dbgfs(struct idt_ntb_dev *ndev)
2508 {
2509 char devname[64];
2510
2511
2512 if (IS_ERR_OR_NULL(dbgfs_topdir)) {
2513 dev_info(&ndev->ntb.pdev->dev, "Top DebugFS directory absent");
2514 return PTR_ERR_OR_ZERO(dbgfs_topdir);
2515 }
2516
2517
2518 snprintf(devname, 64, "info:%s", pci_name(ndev->ntb.pdev));
2519 ndev->dbgfs_info = debugfs_create_file(devname, 0400, dbgfs_topdir,
2520 ndev, &idt_dbgfs_info_ops);
2521 if (IS_ERR(ndev->dbgfs_info)) {
2522 dev_dbg(&ndev->ntb.pdev->dev, "Failed to create DebugFS node");
2523 return PTR_ERR(ndev->dbgfs_info);
2524 }
2525
2526 dev_dbg(&ndev->ntb.pdev->dev, "NTB device DebugFS node created");
2527
2528 return 0;
2529 }
2530
2531
2532
2533
2534
2535
2536
2537 static void idt_deinit_dbgfs(struct idt_ntb_dev *ndev)
2538 {
2539 debugfs_remove(ndev->dbgfs_info);
2540
2541 dev_dbg(&ndev->ntb.pdev->dev, "NTB device DebugFS node discarded");
2542 }
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556 static int idt_check_setup(struct pci_dev *pdev)
2557 {
2558 u32 data;
2559 int ret;
2560
2561
2562 ret = pci_read_config_dword(pdev, IDT_NT_BARSETUP0, &data);
2563 if (ret != 0) {
2564 dev_err(&pdev->dev,
2565 "Failed to read BARSETUP0 config register");
2566 return ret;
2567 }
2568
2569
2570 if (!(data & IDT_BARSETUP_EN) || !(data & IDT_BARSETUP_MODE_CFG)) {
2571 dev_err(&pdev->dev, "BAR0 doesn't map config space");
2572 return -EINVAL;
2573 }
2574
2575
2576 if ((data & IDT_BARSETUP_SIZE_MASK) != IDT_BARSETUP_SIZE_CFG) {
2577 dev_err(&pdev->dev, "Invalid size of config space");
2578 return -EINVAL;
2579 }
2580
2581 dev_dbg(&pdev->dev, "NTB device pre-initialized correctly");
2582
2583 return 0;
2584 }
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599 static struct idt_ntb_dev *idt_create_dev(struct pci_dev *pdev,
2600 const struct pci_device_id *id)
2601 {
2602 struct idt_ntb_dev *ndev;
2603
2604
2605 ndev = devm_kzalloc(&pdev->dev, sizeof(*ndev), GFP_KERNEL);
2606 if (!ndev) {
2607 dev_err(&pdev->dev, "Memory allocation failed for descriptor");
2608 return ERR_PTR(-ENOMEM);
2609 }
2610
2611
2612 ndev->swcfg = (struct idt_89hpes_cfg *)id->driver_data;
2613
2614 ndev->ntb.pdev = pdev;
2615
2616
2617 spin_lock_init(&ndev->db_mask_lock);
2618 spin_lock_init(&ndev->msg_mask_lock);
2619 spin_lock_init(&ndev->gasa_lock);
2620
2621 dev_info(&pdev->dev, "IDT %s discovered", ndev->swcfg->name);
2622
2623 dev_dbg(&pdev->dev, "NTB device descriptor created");
2624
2625 return ndev;
2626 }
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637 static int idt_init_pci(struct idt_ntb_dev *ndev)
2638 {
2639 struct pci_dev *pdev = ndev->ntb.pdev;
2640 int ret;
2641
2642
2643 ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
2644 if (ret != 0) {
2645 ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
2646 if (ret != 0) {
2647 dev_err(&pdev->dev, "Failed to set DMA bit mask\n");
2648 return ret;
2649 }
2650 dev_warn(&pdev->dev, "Cannot set DMA highmem bit mask\n");
2651 }
2652
2653
2654
2655
2656
2657 ret = pci_enable_pcie_error_reporting(pdev);
2658 if (ret != 0)
2659 dev_warn(&pdev->dev, "PCIe AER capability disabled\n");
2660 else
2661 pci_aer_clear_nonfatal_status(pdev);
2662
2663
2664 ret = pcim_enable_device(pdev);
2665 if (ret != 0) {
2666 dev_err(&pdev->dev, "Failed to enable PCIe device\n");
2667 goto err_disable_aer;
2668 }
2669
2670
2671
2672
2673
2674 pci_set_master(pdev);
2675
2676
2677 ret = pcim_iomap_regions_request_all(pdev, 1, NTB_NAME);
2678 if (ret != 0) {
2679 dev_err(&pdev->dev, "Failed to request resources\n");
2680 goto err_clear_master;
2681 }
2682
2683
2684 ndev->cfgspc = pcim_iomap_table(pdev)[0];
2685
2686
2687 pci_set_drvdata(pdev, ndev);
2688
2689 dev_dbg(&pdev->dev, "NT-function PCIe interface initialized");
2690
2691 return 0;
2692
2693 err_clear_master:
2694 pci_clear_master(pdev);
2695 err_disable_aer:
2696 (void)pci_disable_pcie_error_reporting(pdev);
2697
2698 return ret;
2699 }
2700
2701
2702
2703
2704
2705
2706
2707 static void idt_deinit_pci(struct idt_ntb_dev *ndev)
2708 {
2709 struct pci_dev *pdev = ndev->ntb.pdev;
2710
2711
2712 pci_set_drvdata(pdev, NULL);
2713
2714
2715 pci_clear_master(pdev);
2716
2717
2718 (void)pci_disable_pcie_error_reporting(pdev);
2719
2720 dev_dbg(&pdev->dev, "NT-function PCIe interface cleared");
2721 }
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735 static int idt_pci_probe(struct pci_dev *pdev,
2736 const struct pci_device_id *id)
2737 {
2738 struct idt_ntb_dev *ndev;
2739 int ret;
2740
2741
2742 ret = idt_check_setup(pdev);
2743 if (ret != 0)
2744 return ret;
2745
2746
2747 ndev = idt_create_dev(pdev, id);
2748 if (IS_ERR(ndev))
2749 return PTR_ERR(ndev);
2750
2751
2752 ret = idt_init_pci(ndev);
2753 if (ret != 0)
2754 return ret;
2755
2756
2757 (void)idt_scan_ports(ndev);
2758
2759
2760 idt_init_link(ndev);
2761
2762
2763 ret = idt_init_mws(ndev);
2764 if (ret != 0)
2765 goto err_deinit_link;
2766
2767
2768 idt_init_msg(ndev);
2769
2770
2771 idt_init_temp(ndev);
2772
2773
2774 ret = idt_init_isr(ndev);
2775 if (ret != 0)
2776 goto err_deinit_link;
2777
2778
2779 ret = idt_register_device(ndev);
2780 if (ret != 0)
2781 goto err_deinit_isr;
2782
2783
2784 (void)idt_init_dbgfs(ndev);
2785
2786
2787 dev_info(&pdev->dev, "IDT NTB device is ready");
2788
2789
2790 return 0;
2791
2792 err_deinit_isr:
2793 idt_deinit_isr(ndev);
2794 err_deinit_link:
2795 idt_deinit_link(ndev);
2796 idt_deinit_pci(ndev);
2797
2798 return ret;
2799 }
2800
2801
2802
2803
2804
2805 static void idt_pci_remove(struct pci_dev *pdev)
2806 {
2807 struct idt_ntb_dev *ndev = pci_get_drvdata(pdev);
2808
2809
2810 idt_deinit_dbgfs(ndev);
2811
2812
2813 idt_unregister_device(ndev);
2814
2815
2816 idt_deinit_isr(ndev);
2817
2818
2819 idt_deinit_link(ndev);
2820
2821
2822 idt_deinit_pci(ndev);
2823
2824
2825 dev_info(&pdev->dev, "IDT NTB device is removed");
2826
2827
2828 }
2829
2830
2831
2832
2833 static const struct idt_89hpes_cfg idt_89hpes24nt6ag2_config = {
2834 .name = "89HPES24NT6AG2",
2835 .port_cnt = 6, .ports = {0, 2, 4, 6, 8, 12}
2836 };
2837 static const struct idt_89hpes_cfg idt_89hpes32nt8ag2_config = {
2838 .name = "89HPES32NT8AG2",
2839 .port_cnt = 8, .ports = {0, 2, 4, 6, 8, 12, 16, 20}
2840 };
2841 static const struct idt_89hpes_cfg idt_89hpes32nt8bg2_config = {
2842 .name = "89HPES32NT8BG2",
2843 .port_cnt = 8, .ports = {0, 2, 4, 6, 8, 12, 16, 20}
2844 };
2845 static const struct idt_89hpes_cfg idt_89hpes12nt12g2_config = {
2846 .name = "89HPES12NT12G2",
2847 .port_cnt = 3, .ports = {0, 8, 16}
2848 };
2849 static const struct idt_89hpes_cfg idt_89hpes16nt16g2_config = {
2850 .name = "89HPES16NT16G2",
2851 .port_cnt = 4, .ports = {0, 8, 12, 16}
2852 };
2853 static const struct idt_89hpes_cfg idt_89hpes24nt24g2_config = {
2854 .name = "89HPES24NT24G2",
2855 .port_cnt = 8, .ports = {0, 2, 4, 6, 8, 12, 16, 20}
2856 };
2857 static const struct idt_89hpes_cfg idt_89hpes32nt24ag2_config = {
2858 .name = "89HPES32NT24AG2",
2859 .port_cnt = 8, .ports = {0, 2, 4, 6, 8, 12, 16, 20}
2860 };
2861 static const struct idt_89hpes_cfg idt_89hpes32nt24bg2_config = {
2862 .name = "89HPES32NT24BG2",
2863 .port_cnt = 8, .ports = {0, 2, 4, 6, 8, 12, 16, 20}
2864 };
2865
2866
2867
2868
2869 static const struct pci_device_id idt_pci_tbl[] = {
2870 {IDT_PCI_DEVICE_IDS(89HPES24NT6AG2, idt_89hpes24nt6ag2_config)},
2871 {IDT_PCI_DEVICE_IDS(89HPES32NT8AG2, idt_89hpes32nt8ag2_config)},
2872 {IDT_PCI_DEVICE_IDS(89HPES32NT8BG2, idt_89hpes32nt8bg2_config)},
2873 {IDT_PCI_DEVICE_IDS(89HPES12NT12G2, idt_89hpes12nt12g2_config)},
2874 {IDT_PCI_DEVICE_IDS(89HPES16NT16G2, idt_89hpes16nt16g2_config)},
2875 {IDT_PCI_DEVICE_IDS(89HPES24NT24G2, idt_89hpes24nt24g2_config)},
2876 {IDT_PCI_DEVICE_IDS(89HPES32NT24AG2, idt_89hpes32nt24ag2_config)},
2877 {IDT_PCI_DEVICE_IDS(89HPES32NT24BG2, idt_89hpes32nt24bg2_config)},
2878 {0}
2879 };
2880 MODULE_DEVICE_TABLE(pci, idt_pci_tbl);
2881
2882
2883
2884
2885 static struct pci_driver idt_pci_driver = {
2886 .name = KBUILD_MODNAME,
2887 .probe = idt_pci_probe,
2888 .remove = idt_pci_remove,
2889 .id_table = idt_pci_tbl,
2890 };
2891
2892 static int __init idt_pci_driver_init(void)
2893 {
2894 pr_info("%s %s\n", NTB_DESC, NTB_VER);
2895
2896
2897 if (debugfs_initialized())
2898 dbgfs_topdir = debugfs_create_dir(KBUILD_MODNAME, NULL);
2899
2900
2901 return pci_register_driver(&idt_pci_driver);
2902 }
2903 module_init(idt_pci_driver_init);
2904
2905 static void __exit idt_pci_driver_exit(void)
2906 {
2907
2908 pci_unregister_driver(&idt_pci_driver);
2909
2910
2911 debugfs_remove_recursive(dbgfs_topdir);
2912 }
2913 module_exit(idt_pci_driver_exit);
2914