0001
0002
0003
0004
0005
0006 #include <linux/delay.h>
0007 #include <linux/pci.h>
0008 #include <linux/vmalloc.h>
0009
0010 #include "hfi.h"
0011
0012
0013 static inline u32 i2c_in_csr(u32 bus_num)
0014 {
0015 return bus_num ? ASIC_QSFP2_IN : ASIC_QSFP1_IN;
0016 }
0017
0018
0019 static inline u32 i2c_oe_csr(u32 bus_num)
0020 {
0021 return bus_num ? ASIC_QSFP2_OE : ASIC_QSFP1_OE;
0022 }
0023
0024 static void hfi1_setsda(void *data, int state)
0025 {
0026 struct hfi1_i2c_bus *bus = (struct hfi1_i2c_bus *)data;
0027 struct hfi1_devdata *dd = bus->controlling_dd;
0028 u64 reg;
0029 u32 target_oe;
0030
0031 target_oe = i2c_oe_csr(bus->num);
0032 reg = read_csr(dd, target_oe);
0033
0034
0035
0036
0037
0038
0039 if (state)
0040 reg &= ~QSFP_HFI0_I2CDAT;
0041 else
0042 reg |= QSFP_HFI0_I2CDAT;
0043 write_csr(dd, target_oe, reg);
0044
0045 (void)read_csr(dd, target_oe);
0046 }
0047
0048 static void hfi1_setscl(void *data, int state)
0049 {
0050 struct hfi1_i2c_bus *bus = (struct hfi1_i2c_bus *)data;
0051 struct hfi1_devdata *dd = bus->controlling_dd;
0052 u64 reg;
0053 u32 target_oe;
0054
0055 target_oe = i2c_oe_csr(bus->num);
0056 reg = read_csr(dd, target_oe);
0057
0058
0059
0060
0061
0062
0063 if (state)
0064 reg &= ~QSFP_HFI0_I2CCLK;
0065 else
0066 reg |= QSFP_HFI0_I2CCLK;
0067 write_csr(dd, target_oe, reg);
0068
0069 (void)read_csr(dd, target_oe);
0070 }
0071
0072 static int hfi1_getsda(void *data)
0073 {
0074 struct hfi1_i2c_bus *bus = (struct hfi1_i2c_bus *)data;
0075 u64 reg;
0076 u32 target_in;
0077
0078 hfi1_setsda(data, 1);
0079 udelay(2);
0080
0081 target_in = i2c_in_csr(bus->num);
0082 reg = read_csr(bus->controlling_dd, target_in);
0083 return !!(reg & QSFP_HFI0_I2CDAT);
0084 }
0085
0086 static int hfi1_getscl(void *data)
0087 {
0088 struct hfi1_i2c_bus *bus = (struct hfi1_i2c_bus *)data;
0089 u64 reg;
0090 u32 target_in;
0091
0092 hfi1_setscl(data, 1);
0093 udelay(2);
0094
0095 target_in = i2c_in_csr(bus->num);
0096 reg = read_csr(bus->controlling_dd, target_in);
0097 return !!(reg & QSFP_HFI0_I2CCLK);
0098 }
0099
0100
0101
0102
0103
0104 static struct hfi1_i2c_bus *init_i2c_bus(struct hfi1_devdata *dd,
0105 struct hfi1_asic_data *ad, int num)
0106 {
0107 struct hfi1_i2c_bus *bus;
0108 int ret;
0109
0110 bus = kzalloc(sizeof(*bus), GFP_KERNEL);
0111 if (!bus)
0112 return NULL;
0113
0114 bus->controlling_dd = dd;
0115 bus->num = num;
0116
0117 bus->algo.setsda = hfi1_setsda;
0118 bus->algo.setscl = hfi1_setscl;
0119 bus->algo.getsda = hfi1_getsda;
0120 bus->algo.getscl = hfi1_getscl;
0121 bus->algo.udelay = 5;
0122 bus->algo.timeout = usecs_to_jiffies(100000);
0123 bus->algo.data = bus;
0124
0125 bus->adapter.owner = THIS_MODULE;
0126 bus->adapter.algo_data = &bus->algo;
0127 bus->adapter.dev.parent = &dd->pcidev->dev;
0128 snprintf(bus->adapter.name, sizeof(bus->adapter.name),
0129 "hfi1_i2c%d", num);
0130
0131 ret = i2c_bit_add_bus(&bus->adapter);
0132 if (ret) {
0133 dd_dev_info(dd, "%s: unable to add i2c bus %d, err %d\n",
0134 __func__, num, ret);
0135 kfree(bus);
0136 return NULL;
0137 }
0138
0139 return bus;
0140 }
0141
0142
0143
0144
0145
0146 int set_up_i2c(struct hfi1_devdata *dd, struct hfi1_asic_data *ad)
0147 {
0148 ad->i2c_bus0 = init_i2c_bus(dd, ad, 0);
0149 ad->i2c_bus1 = init_i2c_bus(dd, ad, 1);
0150 if (!ad->i2c_bus0 || !ad->i2c_bus1)
0151 return -ENOMEM;
0152 return 0;
0153 };
0154
0155 static void clean_i2c_bus(struct hfi1_i2c_bus *bus)
0156 {
0157 if (bus) {
0158 i2c_del_adapter(&bus->adapter);
0159 kfree(bus);
0160 }
0161 }
0162
0163 void clean_up_i2c(struct hfi1_devdata *dd, struct hfi1_asic_data *ad)
0164 {
0165 if (!ad)
0166 return;
0167 clean_i2c_bus(ad->i2c_bus0);
0168 ad->i2c_bus0 = NULL;
0169 clean_i2c_bus(ad->i2c_bus1);
0170 ad->i2c_bus1 = NULL;
0171 }
0172
0173 static int i2c_bus_write(struct hfi1_devdata *dd, struct hfi1_i2c_bus *i2c,
0174 u8 slave_addr, int offset, int offset_size,
0175 u8 *data, u16 len)
0176 {
0177 int ret;
0178 int num_msgs;
0179 u8 offset_bytes[2];
0180 struct i2c_msg msgs[2];
0181
0182 switch (offset_size) {
0183 case 0:
0184 num_msgs = 1;
0185 msgs[0].addr = slave_addr;
0186 msgs[0].flags = 0;
0187 msgs[0].len = len;
0188 msgs[0].buf = data;
0189 break;
0190 case 2:
0191 offset_bytes[1] = (offset >> 8) & 0xff;
0192 fallthrough;
0193 case 1:
0194 num_msgs = 2;
0195 offset_bytes[0] = offset & 0xff;
0196
0197 msgs[0].addr = slave_addr;
0198 msgs[0].flags = 0;
0199 msgs[0].len = offset_size;
0200 msgs[0].buf = offset_bytes;
0201
0202 msgs[1].addr = slave_addr;
0203 msgs[1].flags = I2C_M_NOSTART;
0204 msgs[1].len = len;
0205 msgs[1].buf = data;
0206 break;
0207 default:
0208 return -EINVAL;
0209 }
0210
0211 i2c->controlling_dd = dd;
0212 ret = i2c_transfer(&i2c->adapter, msgs, num_msgs);
0213 if (ret != num_msgs) {
0214 dd_dev_err(dd, "%s: bus %d, i2c slave 0x%x, offset 0x%x, len 0x%x; write failed, ret %d\n",
0215 __func__, i2c->num, slave_addr, offset, len, ret);
0216 return ret < 0 ? ret : -EIO;
0217 }
0218 return 0;
0219 }
0220
0221 static int i2c_bus_read(struct hfi1_devdata *dd, struct hfi1_i2c_bus *bus,
0222 u8 slave_addr, int offset, int offset_size,
0223 u8 *data, u16 len)
0224 {
0225 int ret;
0226 int num_msgs;
0227 u8 offset_bytes[2];
0228 struct i2c_msg msgs[2];
0229
0230 switch (offset_size) {
0231 case 0:
0232 num_msgs = 1;
0233 msgs[0].addr = slave_addr;
0234 msgs[0].flags = I2C_M_RD;
0235 msgs[0].len = len;
0236 msgs[0].buf = data;
0237 break;
0238 case 2:
0239 offset_bytes[1] = (offset >> 8) & 0xff;
0240 fallthrough;
0241 case 1:
0242 num_msgs = 2;
0243 offset_bytes[0] = offset & 0xff;
0244
0245 msgs[0].addr = slave_addr;
0246 msgs[0].flags = 0;
0247 msgs[0].len = offset_size;
0248 msgs[0].buf = offset_bytes;
0249
0250 msgs[1].addr = slave_addr;
0251 msgs[1].flags = I2C_M_RD;
0252 msgs[1].len = len;
0253 msgs[1].buf = data;
0254 break;
0255 default:
0256 return -EINVAL;
0257 }
0258
0259 bus->controlling_dd = dd;
0260 ret = i2c_transfer(&bus->adapter, msgs, num_msgs);
0261 if (ret != num_msgs) {
0262 dd_dev_err(dd, "%s: bus %d, i2c slave 0x%x, offset 0x%x, len 0x%x; read failed, ret %d\n",
0263 __func__, bus->num, slave_addr, offset, len, ret);
0264 return ret < 0 ? ret : -EIO;
0265 }
0266 return 0;
0267 }
0268
0269
0270
0271
0272
0273
0274 static int __i2c_write(struct hfi1_pportdata *ppd, u32 target, int i2c_addr,
0275 int offset, void *bp, int len)
0276 {
0277 struct hfi1_devdata *dd = ppd->dd;
0278 struct hfi1_i2c_bus *bus;
0279 u8 slave_addr;
0280 int offset_size;
0281
0282 bus = target ? dd->asic_data->i2c_bus1 : dd->asic_data->i2c_bus0;
0283 slave_addr = (i2c_addr & 0xff) >> 1;
0284 offset_size = (i2c_addr >> 8) & 0x3;
0285 return i2c_bus_write(dd, bus, slave_addr, offset, offset_size, bp, len);
0286 }
0287
0288
0289
0290
0291
0292
0293 int i2c_write(struct hfi1_pportdata *ppd, u32 target, int i2c_addr, int offset,
0294 void *bp, int len)
0295 {
0296 int ret;
0297
0298 if (!check_chip_resource(ppd->dd, i2c_target(target), __func__))
0299 return -EACCES;
0300
0301 ret = __i2c_write(ppd, target, i2c_addr, offset, bp, len);
0302 if (ret)
0303 return ret;
0304
0305 return len;
0306 }
0307
0308
0309
0310
0311
0312
0313 static int __i2c_read(struct hfi1_pportdata *ppd, u32 target, int i2c_addr,
0314 int offset, void *bp, int len)
0315 {
0316 struct hfi1_devdata *dd = ppd->dd;
0317 struct hfi1_i2c_bus *bus;
0318 u8 slave_addr;
0319 int offset_size;
0320
0321 bus = target ? dd->asic_data->i2c_bus1 : dd->asic_data->i2c_bus0;
0322 slave_addr = (i2c_addr & 0xff) >> 1;
0323 offset_size = (i2c_addr >> 8) & 0x3;
0324 return i2c_bus_read(dd, bus, slave_addr, offset, offset_size, bp, len);
0325 }
0326
0327
0328
0329
0330
0331
0332 int i2c_read(struct hfi1_pportdata *ppd, u32 target, int i2c_addr, int offset,
0333 void *bp, int len)
0334 {
0335 int ret;
0336
0337 if (!check_chip_resource(ppd->dd, i2c_target(target), __func__))
0338 return -EACCES;
0339
0340 ret = __i2c_read(ppd, target, i2c_addr, offset, bp, len);
0341 if (ret)
0342 return ret;
0343
0344 return len;
0345 }
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355 int qsfp_write(struct hfi1_pportdata *ppd, u32 target, int addr, void *bp,
0356 int len)
0357 {
0358 int count = 0;
0359 int offset;
0360 int nwrite;
0361 int ret = 0;
0362 u8 page;
0363
0364 if (!check_chip_resource(ppd->dd, i2c_target(target), __func__))
0365 return -EACCES;
0366
0367 while (count < len) {
0368
0369
0370
0371
0372 page = (u8)(addr / QSFP_PAGESIZE);
0373
0374 ret = __i2c_write(ppd, target, QSFP_DEV | QSFP_OFFSET_SIZE,
0375 QSFP_PAGE_SELECT_BYTE_OFFS, &page, 1);
0376
0377 mdelay(5);
0378 if (ret) {
0379 hfi1_dev_porterr(ppd->dd, ppd->port,
0380 "QSFP chain %d can't write QSFP_PAGE_SELECT_BYTE: %d\n",
0381 target, ret);
0382 break;
0383 }
0384
0385 offset = addr % QSFP_PAGESIZE;
0386 nwrite = len - count;
0387
0388 if (((addr % QSFP_RW_BOUNDARY) + nwrite) > QSFP_RW_BOUNDARY)
0389 nwrite = QSFP_RW_BOUNDARY - (addr % QSFP_RW_BOUNDARY);
0390
0391 ret = __i2c_write(ppd, target, QSFP_DEV | QSFP_OFFSET_SIZE,
0392 offset, bp + count, nwrite);
0393
0394 mdelay(5);
0395 if (ret)
0396 break;
0397
0398 count += nwrite;
0399 addr += nwrite;
0400 }
0401
0402 if (ret < 0)
0403 return ret;
0404 return count;
0405 }
0406
0407
0408
0409
0410
0411 int one_qsfp_write(struct hfi1_pportdata *ppd, u32 target, int addr, void *bp,
0412 int len)
0413 {
0414 struct hfi1_devdata *dd = ppd->dd;
0415 u32 resource = qsfp_resource(dd);
0416 int ret;
0417
0418 ret = acquire_chip_resource(dd, resource, QSFP_WAIT);
0419 if (ret)
0420 return ret;
0421 ret = qsfp_write(ppd, target, addr, bp, len);
0422 release_chip_resource(dd, resource);
0423
0424 return ret;
0425 }
0426
0427
0428
0429
0430
0431
0432
0433
0434
0435 int qsfp_read(struct hfi1_pportdata *ppd, u32 target, int addr, void *bp,
0436 int len)
0437 {
0438 int count = 0;
0439 int offset;
0440 int nread;
0441 int ret = 0;
0442 u8 page;
0443
0444 if (!check_chip_resource(ppd->dd, i2c_target(target), __func__))
0445 return -EACCES;
0446
0447 while (count < len) {
0448
0449
0450
0451
0452 page = (u8)(addr / QSFP_PAGESIZE);
0453 ret = __i2c_write(ppd, target, QSFP_DEV | QSFP_OFFSET_SIZE,
0454 QSFP_PAGE_SELECT_BYTE_OFFS, &page, 1);
0455
0456 mdelay(5);
0457 if (ret) {
0458 hfi1_dev_porterr(ppd->dd, ppd->port,
0459 "QSFP chain %d can't write QSFP_PAGE_SELECT_BYTE: %d\n",
0460 target, ret);
0461 break;
0462 }
0463
0464 offset = addr % QSFP_PAGESIZE;
0465 nread = len - count;
0466
0467 if (((addr % QSFP_RW_BOUNDARY) + nread) > QSFP_RW_BOUNDARY)
0468 nread = QSFP_RW_BOUNDARY - (addr % QSFP_RW_BOUNDARY);
0469
0470 ret = __i2c_read(ppd, target, QSFP_DEV | QSFP_OFFSET_SIZE,
0471 offset, bp + count, nread);
0472 if (ret)
0473 break;
0474
0475 count += nread;
0476 addr += nread;
0477 }
0478
0479 if (ret < 0)
0480 return ret;
0481 return count;
0482 }
0483
0484
0485
0486
0487
0488 int one_qsfp_read(struct hfi1_pportdata *ppd, u32 target, int addr, void *bp,
0489 int len)
0490 {
0491 struct hfi1_devdata *dd = ppd->dd;
0492 u32 resource = qsfp_resource(dd);
0493 int ret;
0494
0495 ret = acquire_chip_resource(dd, resource, QSFP_WAIT);
0496 if (ret)
0497 return ret;
0498 ret = qsfp_read(ppd, target, addr, bp, len);
0499 release_chip_resource(dd, resource);
0500
0501 return ret;
0502 }
0503
0504
0505
0506
0507
0508
0509
0510
0511
0512
0513
0514
0515
0516 int refresh_qsfp_cache(struct hfi1_pportdata *ppd, struct qsfp_data *cp)
0517 {
0518 u32 target = ppd->dd->hfi1_id;
0519 int ret;
0520 unsigned long flags;
0521 u8 *cache = &cp->cache[0];
0522
0523
0524 memset(cache, 0, (QSFP_MAX_NUM_PAGES * 128));
0525 spin_lock_irqsave(&ppd->qsfp_info.qsfp_lock, flags);
0526 ppd->qsfp_info.cache_valid = 0;
0527 spin_unlock_irqrestore(&ppd->qsfp_info.qsfp_lock, flags);
0528
0529 if (!qsfp_mod_present(ppd)) {
0530 ret = -ENODEV;
0531 goto bail;
0532 }
0533
0534 ret = qsfp_read(ppd, target, 0, cache, QSFP_PAGESIZE);
0535 if (ret != QSFP_PAGESIZE) {
0536 dd_dev_info(ppd->dd,
0537 "%s: Page 0 read failed, expected %d, got %d\n",
0538 __func__, QSFP_PAGESIZE, ret);
0539 goto bail;
0540 }
0541
0542
0543 if (!(cache[2] & 4)) {
0544
0545 if ((cache[195] & 0xC0) == 0xC0) {
0546
0547 ret = qsfp_read(ppd, target, 384, cache + 256, 128);
0548 if (ret <= 0 || ret != 128) {
0549 dd_dev_info(ppd->dd, "%s failed\n", __func__);
0550 goto bail;
0551 }
0552 ret = qsfp_read(ppd, target, 640, cache + 384, 128);
0553 if (ret <= 0 || ret != 128) {
0554 dd_dev_info(ppd->dd, "%s failed\n", __func__);
0555 goto bail;
0556 }
0557 ret = qsfp_read(ppd, target, 896, cache + 512, 128);
0558 if (ret <= 0 || ret != 128) {
0559 dd_dev_info(ppd->dd, "%s failed\n", __func__);
0560 goto bail;
0561 }
0562 } else if ((cache[195] & 0x80) == 0x80) {
0563
0564 ret = qsfp_read(ppd, target, 640, cache + 384, 128);
0565 if (ret <= 0 || ret != 128) {
0566 dd_dev_info(ppd->dd, "%s failed\n", __func__);
0567 goto bail;
0568 }
0569 ret = qsfp_read(ppd, target, 896, cache + 512, 128);
0570 if (ret <= 0 || ret != 128) {
0571 dd_dev_info(ppd->dd, "%s failed\n", __func__);
0572 goto bail;
0573 }
0574 } else if ((cache[195] & 0x40) == 0x40) {
0575
0576 ret = qsfp_read(ppd, target, 384, cache + 256, 128);
0577 if (ret <= 0 || ret != 128) {
0578 dd_dev_info(ppd->dd, "%s failed\n", __func__);
0579 goto bail;
0580 }
0581 ret = qsfp_read(ppd, target, 896, cache + 512, 128);
0582 if (ret <= 0 || ret != 128) {
0583 dd_dev_info(ppd->dd, "%s failed\n", __func__);
0584 goto bail;
0585 }
0586 } else {
0587
0588 ret = qsfp_read(ppd, target, 896, cache + 512, 128);
0589 if (ret <= 0 || ret != 128) {
0590 dd_dev_info(ppd->dd, "%s failed\n", __func__);
0591 goto bail;
0592 }
0593 }
0594 }
0595
0596 spin_lock_irqsave(&ppd->qsfp_info.qsfp_lock, flags);
0597 ppd->qsfp_info.cache_valid = 1;
0598 ppd->qsfp_info.cache_refresh_required = 0;
0599 spin_unlock_irqrestore(&ppd->qsfp_info.qsfp_lock, flags);
0600
0601 return 0;
0602
0603 bail:
0604 memset(cache, 0, (QSFP_MAX_NUM_PAGES * 128));
0605 return ret;
0606 }
0607
0608 const char * const hfi1_qsfp_devtech[16] = {
0609 "850nm VCSEL", "1310nm VCSEL", "1550nm VCSEL", "1310nm FP",
0610 "1310nm DFB", "1550nm DFB", "1310nm EML", "1550nm EML",
0611 "Cu Misc", "1490nm DFB", "Cu NoEq", "Cu Eq",
0612 "Undef", "Cu Active BothEq", "Cu FarEq", "Cu NearEq"
0613 };
0614
0615 #define QSFP_DUMP_CHUNK 16
0616 #define QSFP_DEFAULT_HDR_CNT 224
0617
0618 #define QSFP_PWR(pbyte) (((pbyte) >> 6) & 3)
0619 #define QSFP_HIGH_PWR(pbyte) ((pbyte) & 3)
0620
0621 #define QSFP_HIGH_PWR_UNUSED 0
0622
0623
0624
0625
0626
0627 int get_qsfp_power_class(u8 power_byte)
0628 {
0629 if (QSFP_HIGH_PWR(power_byte) == QSFP_HIGH_PWR_UNUSED)
0630
0631 return (QSFP_PWR(power_byte) + 1);
0632
0633
0634
0635
0636
0637
0638 return (QSFP_HIGH_PWR(power_byte) + 4);
0639 }
0640
0641 int qsfp_mod_present(struct hfi1_pportdata *ppd)
0642 {
0643 struct hfi1_devdata *dd = ppd->dd;
0644 u64 reg;
0645
0646 reg = read_csr(dd, dd->hfi1_id ? ASIC_QSFP2_IN : ASIC_QSFP1_IN);
0647 return !(reg & QSFP_HFI0_MODPRST_N);
0648 }
0649
0650
0651
0652
0653
0654
0655
0656
0657
0658
0659
0660
0661
0662
0663
0664
0665 int get_cable_info(struct hfi1_devdata *dd, u32 port_num, u32 addr, u32 len,
0666 u8 *data)
0667 {
0668 struct hfi1_pportdata *ppd;
0669 u32 excess_len = len;
0670 int ret = 0, offset = 0;
0671
0672 if (port_num > dd->num_pports || port_num < 1) {
0673 dd_dev_info(dd, "%s: Invalid port number %d\n",
0674 __func__, port_num);
0675 ret = -EINVAL;
0676 goto set_zeroes;
0677 }
0678
0679 ppd = dd->pport + (port_num - 1);
0680 if (!qsfp_mod_present(ppd)) {
0681 ret = -ENODEV;
0682 goto set_zeroes;
0683 }
0684
0685 if (!ppd->qsfp_info.cache_valid) {
0686 ret = -EINVAL;
0687 goto set_zeroes;
0688 }
0689
0690 if (addr >= (QSFP_MAX_NUM_PAGES * 128)) {
0691 ret = -ERANGE;
0692 goto set_zeroes;
0693 }
0694
0695 if ((addr + len) > (QSFP_MAX_NUM_PAGES * 128)) {
0696 excess_len = (addr + len) - (QSFP_MAX_NUM_PAGES * 128);
0697 memcpy(data, &ppd->qsfp_info.cache[addr], (len - excess_len));
0698 data += (len - excess_len);
0699 goto set_zeroes;
0700 }
0701
0702 memcpy(data, &ppd->qsfp_info.cache[addr], len);
0703
0704 if (addr <= QSFP_MONITOR_VAL_END &&
0705 (addr + len) >= QSFP_MONITOR_VAL_START) {
0706
0707 if (addr < QSFP_MONITOR_VAL_START) {
0708 if (addr + len <= QSFP_MONITOR_VAL_END)
0709 len = addr + len - QSFP_MONITOR_VAL_START;
0710 else
0711 len = QSFP_MONITOR_RANGE;
0712 offset = QSFP_MONITOR_VAL_START - addr;
0713 addr = QSFP_MONITOR_VAL_START;
0714 } else if (addr == QSFP_MONITOR_VAL_START) {
0715 offset = 0;
0716 if (addr + len > QSFP_MONITOR_VAL_END)
0717 len = QSFP_MONITOR_RANGE;
0718 } else {
0719 offset = 0;
0720 if (addr + len > QSFP_MONITOR_VAL_END)
0721 len = QSFP_MONITOR_VAL_END - addr + 1;
0722 }
0723
0724 ret = one_qsfp_read(ppd, dd->hfi1_id, addr, data + offset, len);
0725 if (ret != len) {
0726 ret = -EAGAIN;
0727 goto set_zeroes;
0728 }
0729 }
0730
0731 return 0;
0732
0733 set_zeroes:
0734 memset(data, 0, excess_len);
0735 return ret;
0736 }
0737
0738 static const char *pwr_codes[8] = {"N/AW",
0739 "1.5W",
0740 "2.0W",
0741 "2.5W",
0742 "3.5W",
0743 "4.0W",
0744 "4.5W",
0745 "5.0W"
0746 };
0747
0748 int qsfp_dump(struct hfi1_pportdata *ppd, char *buf, int len)
0749 {
0750 u8 *cache = &ppd->qsfp_info.cache[0];
0751 u8 bin_buff[QSFP_DUMP_CHUNK];
0752 char lenstr[6];
0753 int sofar;
0754 int bidx = 0;
0755 u8 *atten = &cache[QSFP_ATTEN_OFFS];
0756 u8 *vendor_oui = &cache[QSFP_VOUI_OFFS];
0757 u8 power_byte = 0;
0758
0759 sofar = 0;
0760 lenstr[0] = ' ';
0761 lenstr[1] = '\0';
0762
0763 if (ppd->qsfp_info.cache_valid) {
0764 if (QSFP_IS_CU(cache[QSFP_MOD_TECH_OFFS]))
0765 snprintf(lenstr, sizeof(lenstr), "%dM ",
0766 cache[QSFP_MOD_LEN_OFFS]);
0767
0768 power_byte = cache[QSFP_MOD_PWR_OFFS];
0769 sofar += scnprintf(buf + sofar, len - sofar, "PWR:%.3sW\n",
0770 pwr_codes[get_qsfp_power_class(power_byte)]);
0771
0772 sofar += scnprintf(buf + sofar, len - sofar, "TECH:%s%s\n",
0773 lenstr,
0774 hfi1_qsfp_devtech[(cache[QSFP_MOD_TECH_OFFS]) >> 4]);
0775
0776 sofar += scnprintf(buf + sofar, len - sofar, "Vendor:%.*s\n",
0777 QSFP_VEND_LEN, &cache[QSFP_VEND_OFFS]);
0778
0779 sofar += scnprintf(buf + sofar, len - sofar, "OUI:%06X\n",
0780 QSFP_OUI(vendor_oui));
0781
0782 sofar += scnprintf(buf + sofar, len - sofar, "Part#:%.*s\n",
0783 QSFP_PN_LEN, &cache[QSFP_PN_OFFS]);
0784
0785 sofar += scnprintf(buf + sofar, len - sofar, "Rev:%.*s\n",
0786 QSFP_REV_LEN, &cache[QSFP_REV_OFFS]);
0787
0788 if (QSFP_IS_CU(cache[QSFP_MOD_TECH_OFFS]))
0789 sofar += scnprintf(buf + sofar, len - sofar,
0790 "Atten:%d, %d\n",
0791 QSFP_ATTEN_SDR(atten),
0792 QSFP_ATTEN_DDR(atten));
0793
0794 sofar += scnprintf(buf + sofar, len - sofar, "Serial:%.*s\n",
0795 QSFP_SN_LEN, &cache[QSFP_SN_OFFS]);
0796
0797 sofar += scnprintf(buf + sofar, len - sofar, "Date:%.*s\n",
0798 QSFP_DATE_LEN, &cache[QSFP_DATE_OFFS]);
0799
0800 sofar += scnprintf(buf + sofar, len - sofar, "Lot:%.*s\n",
0801 QSFP_LOT_LEN, &cache[QSFP_LOT_OFFS]);
0802
0803 while (bidx < QSFP_DEFAULT_HDR_CNT) {
0804 int iidx;
0805
0806 memcpy(bin_buff, &cache[bidx], QSFP_DUMP_CHUNK);
0807 for (iidx = 0; iidx < QSFP_DUMP_CHUNK; ++iidx) {
0808 sofar += scnprintf(buf + sofar, len - sofar,
0809 " %02X", bin_buff[iidx]);
0810 }
0811 sofar += scnprintf(buf + sofar, len - sofar, "\n");
0812 bidx += QSFP_DUMP_CHUNK;
0813 }
0814 }
0815 return sofar;
0816 }