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
43
44
45
46
47
48#include <linux/delay.h>
49#include <linux/pci.h>
50#include <linux/vmalloc.h>
51
52#include "hfi.h"
53
54
55static inline u32 i2c_in_csr(u32 bus_num)
56{
57 return bus_num ? ASIC_QSFP2_IN : ASIC_QSFP1_IN;
58}
59
60
61static inline u32 i2c_oe_csr(u32 bus_num)
62{
63 return bus_num ? ASIC_QSFP2_OE : ASIC_QSFP1_OE;
64}
65
66static void hfi1_setsda(void *data, int state)
67{
68 struct hfi1_i2c_bus *bus = (struct hfi1_i2c_bus *)data;
69 struct hfi1_devdata *dd = bus->controlling_dd;
70 u64 reg;
71 u32 target_oe;
72
73 target_oe = i2c_oe_csr(bus->num);
74 reg = read_csr(dd, target_oe);
75
76
77
78
79
80
81 if (state)
82 reg &= ~QSFP_HFI0_I2CDAT;
83 else
84 reg |= QSFP_HFI0_I2CDAT;
85 write_csr(dd, target_oe, reg);
86
87 (void)read_csr(dd, target_oe);
88}
89
90static void hfi1_setscl(void *data, int state)
91{
92 struct hfi1_i2c_bus *bus = (struct hfi1_i2c_bus *)data;
93 struct hfi1_devdata *dd = bus->controlling_dd;
94 u64 reg;
95 u32 target_oe;
96
97 target_oe = i2c_oe_csr(bus->num);
98 reg = read_csr(dd, target_oe);
99
100
101
102
103
104
105 if (state)
106 reg &= ~QSFP_HFI0_I2CCLK;
107 else
108 reg |= QSFP_HFI0_I2CCLK;
109 write_csr(dd, target_oe, reg);
110
111 (void)read_csr(dd, target_oe);
112}
113
114static int hfi1_getsda(void *data)
115{
116 struct hfi1_i2c_bus *bus = (struct hfi1_i2c_bus *)data;
117 u64 reg;
118 u32 target_in;
119
120 hfi1_setsda(data, 1);
121 udelay(2);
122
123 target_in = i2c_in_csr(bus->num);
124 reg = read_csr(bus->controlling_dd, target_in);
125 return !!(reg & QSFP_HFI0_I2CDAT);
126}
127
128static int hfi1_getscl(void *data)
129{
130 struct hfi1_i2c_bus *bus = (struct hfi1_i2c_bus *)data;
131 u64 reg;
132 u32 target_in;
133
134 hfi1_setscl(data, 1);
135 udelay(2);
136
137 target_in = i2c_in_csr(bus->num);
138 reg = read_csr(bus->controlling_dd, target_in);
139 return !!(reg & QSFP_HFI0_I2CCLK);
140}
141
142
143
144
145
146static struct hfi1_i2c_bus *init_i2c_bus(struct hfi1_devdata *dd,
147 struct hfi1_asic_data *ad, int num)
148{
149 struct hfi1_i2c_bus *bus;
150 int ret;
151
152 bus = kzalloc(sizeof(*bus), GFP_KERNEL);
153 if (!bus)
154 return NULL;
155
156 bus->controlling_dd = dd;
157 bus->num = num;
158
159 bus->algo.setsda = hfi1_setsda;
160 bus->algo.setscl = hfi1_setscl;
161 bus->algo.getsda = hfi1_getsda;
162 bus->algo.getscl = hfi1_getscl;
163 bus->algo.udelay = 5;
164 bus->algo.timeout = usecs_to_jiffies(100000);
165 bus->algo.data = bus;
166
167 bus->adapter.owner = THIS_MODULE;
168 bus->adapter.algo_data = &bus->algo;
169 bus->adapter.dev.parent = &dd->pcidev->dev;
170 snprintf(bus->adapter.name, sizeof(bus->adapter.name),
171 "hfi1_i2c%d", num);
172
173 ret = i2c_bit_add_bus(&bus->adapter);
174 if (ret) {
175 dd_dev_info(dd, "%s: unable to add i2c bus %d, err %d\n",
176 __func__, num, ret);
177 kfree(bus);
178 return NULL;
179 }
180
181 return bus;
182}
183
184
185
186
187
188int set_up_i2c(struct hfi1_devdata *dd, struct hfi1_asic_data *ad)
189{
190 ad->i2c_bus0 = init_i2c_bus(dd, ad, 0);
191 ad->i2c_bus1 = init_i2c_bus(dd, ad, 1);
192 if (!ad->i2c_bus0 || !ad->i2c_bus1)
193 return -ENOMEM;
194 return 0;
195};
196
197static void clean_i2c_bus(struct hfi1_i2c_bus *bus)
198{
199 if (bus) {
200 i2c_del_adapter(&bus->adapter);
201 kfree(bus);
202 }
203}
204
205void clean_up_i2c(struct hfi1_devdata *dd, struct hfi1_asic_data *ad)
206{
207 clean_i2c_bus(ad->i2c_bus0);
208 ad->i2c_bus0 = NULL;
209 clean_i2c_bus(ad->i2c_bus1);
210 ad->i2c_bus1 = NULL;
211}
212
213static int i2c_bus_write(struct hfi1_devdata *dd, struct hfi1_i2c_bus *i2c,
214 u8 slave_addr, int offset, int offset_size,
215 u8 *data, u16 len)
216{
217 int ret;
218 int num_msgs;
219 u8 offset_bytes[2];
220 struct i2c_msg msgs[2];
221
222 switch (offset_size) {
223 case 0:
224 num_msgs = 1;
225 msgs[0].addr = slave_addr;
226 msgs[0].flags = 0;
227 msgs[0].len = len;
228 msgs[0].buf = data;
229 break;
230 case 2:
231 offset_bytes[1] = (offset >> 8) & 0xff;
232
233 case 1:
234 num_msgs = 2;
235 offset_bytes[0] = offset & 0xff;
236
237 msgs[0].addr = slave_addr;
238 msgs[0].flags = 0;
239 msgs[0].len = offset_size;
240 msgs[0].buf = offset_bytes;
241
242 msgs[1].addr = slave_addr;
243 msgs[1].flags = I2C_M_NOSTART,
244 msgs[1].len = len;
245 msgs[1].buf = data;
246 break;
247 default:
248 return -EINVAL;
249 }
250
251 i2c->controlling_dd = dd;
252 ret = i2c_transfer(&i2c->adapter, msgs, num_msgs);
253 if (ret != num_msgs) {
254 dd_dev_err(dd, "%s: bus %d, i2c slave 0x%x, offset 0x%x, len 0x%x; write failed, ret %d\n",
255 __func__, i2c->num, slave_addr, offset, len, ret);
256 return ret < 0 ? ret : -EIO;
257 }
258 return 0;
259}
260
261static int i2c_bus_read(struct hfi1_devdata *dd, struct hfi1_i2c_bus *bus,
262 u8 slave_addr, int offset, int offset_size,
263 u8 *data, u16 len)
264{
265 int ret;
266 int num_msgs;
267 u8 offset_bytes[2];
268 struct i2c_msg msgs[2];
269
270 switch (offset_size) {
271 case 0:
272 num_msgs = 1;
273 msgs[0].addr = slave_addr;
274 msgs[0].flags = I2C_M_RD;
275 msgs[0].len = len;
276 msgs[0].buf = data;
277 break;
278 case 2:
279 offset_bytes[1] = (offset >> 8) & 0xff;
280
281 case 1:
282 num_msgs = 2;
283 offset_bytes[0] = offset & 0xff;
284
285 msgs[0].addr = slave_addr;
286 msgs[0].flags = 0;
287 msgs[0].len = offset_size;
288 msgs[0].buf = offset_bytes;
289
290 msgs[1].addr = slave_addr;
291 msgs[1].flags = I2C_M_RD,
292 msgs[1].len = len;
293 msgs[1].buf = data;
294 break;
295 default:
296 return -EINVAL;
297 }
298
299 bus->controlling_dd = dd;
300 ret = i2c_transfer(&bus->adapter, msgs, num_msgs);
301 if (ret != num_msgs) {
302 dd_dev_err(dd, "%s: bus %d, i2c slave 0x%x, offset 0x%x, len 0x%x; read failed, ret %d\n",
303 __func__, bus->num, slave_addr, offset, len, ret);
304 return ret < 0 ? ret : -EIO;
305 }
306 return 0;
307}
308
309
310
311
312
313
314static int __i2c_write(struct hfi1_pportdata *ppd, u32 target, int i2c_addr,
315 int offset, void *bp, int len)
316{
317 struct hfi1_devdata *dd = ppd->dd;
318 struct hfi1_i2c_bus *bus;
319 u8 slave_addr;
320 int offset_size;
321
322 bus = target ? dd->asic_data->i2c_bus1 : dd->asic_data->i2c_bus0;
323 slave_addr = (i2c_addr & 0xff) >> 1;
324 offset_size = (i2c_addr >> 8) & 0x3;
325 return i2c_bus_write(dd, bus, slave_addr, offset, offset_size, bp, len);
326}
327
328
329
330
331
332
333int i2c_write(struct hfi1_pportdata *ppd, u32 target, int i2c_addr, int offset,
334 void *bp, int len)
335{
336 int ret;
337
338 if (!check_chip_resource(ppd->dd, i2c_target(target), __func__))
339 return -EACCES;
340
341 ret = __i2c_write(ppd, target, i2c_addr, offset, bp, len);
342 if (ret)
343 return ret;
344
345 return len;
346}
347
348
349
350
351
352
353static int __i2c_read(struct hfi1_pportdata *ppd, u32 target, int i2c_addr,
354 int offset, void *bp, int len)
355{
356 struct hfi1_devdata *dd = ppd->dd;
357 struct hfi1_i2c_bus *bus;
358 u8 slave_addr;
359 int offset_size;
360
361 bus = target ? dd->asic_data->i2c_bus1 : dd->asic_data->i2c_bus0;
362 slave_addr = (i2c_addr & 0xff) >> 1;
363 offset_size = (i2c_addr >> 8) & 0x3;
364 return i2c_bus_read(dd, bus, slave_addr, offset, offset_size, bp, len);
365}
366
367
368
369
370
371
372int i2c_read(struct hfi1_pportdata *ppd, u32 target, int i2c_addr, int offset,
373 void *bp, int len)
374{
375 int ret;
376
377 if (!check_chip_resource(ppd->dd, i2c_target(target), __func__))
378 return -EACCES;
379
380 ret = __i2c_read(ppd, target, i2c_addr, offset, bp, len);
381 if (ret)
382 return ret;
383
384 return len;
385}
386
387
388
389
390
391
392
393
394
395int qsfp_write(struct hfi1_pportdata *ppd, u32 target, int addr, void *bp,
396 int len)
397{
398 int count = 0;
399 int offset;
400 int nwrite;
401 int ret = 0;
402 u8 page;
403
404 if (!check_chip_resource(ppd->dd, i2c_target(target), __func__))
405 return -EACCES;
406
407 while (count < len) {
408
409
410
411
412 page = (u8)(addr / QSFP_PAGESIZE);
413
414 ret = __i2c_write(ppd, target, QSFP_DEV | QSFP_OFFSET_SIZE,
415 QSFP_PAGE_SELECT_BYTE_OFFS, &page, 1);
416
417 mdelay(5);
418 if (ret) {
419 hfi1_dev_porterr(ppd->dd, ppd->port,
420 "QSFP chain %d can't write QSFP_PAGE_SELECT_BYTE: %d\n",
421 target, ret);
422 break;
423 }
424
425 offset = addr % QSFP_PAGESIZE;
426 nwrite = len - count;
427
428 if (((addr % QSFP_RW_BOUNDARY) + nwrite) > QSFP_RW_BOUNDARY)
429 nwrite = QSFP_RW_BOUNDARY - (addr % QSFP_RW_BOUNDARY);
430
431 ret = __i2c_write(ppd, target, QSFP_DEV | QSFP_OFFSET_SIZE,
432 offset, bp + count, nwrite);
433
434 mdelay(5);
435 if (ret)
436 break;
437
438 count += nwrite;
439 addr += nwrite;
440 }
441
442 if (ret < 0)
443 return ret;
444 return count;
445}
446
447
448
449
450
451int one_qsfp_write(struct hfi1_pportdata *ppd, u32 target, int addr, void *bp,
452 int len)
453{
454 struct hfi1_devdata *dd = ppd->dd;
455 u32 resource = qsfp_resource(dd);
456 int ret;
457
458 ret = acquire_chip_resource(dd, resource, QSFP_WAIT);
459 if (ret)
460 return ret;
461 ret = qsfp_write(ppd, target, addr, bp, len);
462 release_chip_resource(dd, resource);
463
464 return ret;
465}
466
467
468
469
470
471
472
473
474
475int qsfp_read(struct hfi1_pportdata *ppd, u32 target, int addr, void *bp,
476 int len)
477{
478 int count = 0;
479 int offset;
480 int nread;
481 int ret = 0;
482 u8 page;
483
484 if (!check_chip_resource(ppd->dd, i2c_target(target), __func__))
485 return -EACCES;
486
487 while (count < len) {
488
489
490
491
492 page = (u8)(addr / QSFP_PAGESIZE);
493 ret = __i2c_write(ppd, target, QSFP_DEV | QSFP_OFFSET_SIZE,
494 QSFP_PAGE_SELECT_BYTE_OFFS, &page, 1);
495
496 mdelay(5);
497 if (ret) {
498 hfi1_dev_porterr(ppd->dd, ppd->port,
499 "QSFP chain %d can't write QSFP_PAGE_SELECT_BYTE: %d\n",
500 target, ret);
501 break;
502 }
503
504 offset = addr % QSFP_PAGESIZE;
505 nread = len - count;
506
507 if (((addr % QSFP_RW_BOUNDARY) + nread) > QSFP_RW_BOUNDARY)
508 nread = QSFP_RW_BOUNDARY - (addr % QSFP_RW_BOUNDARY);
509
510 ret = __i2c_read(ppd, target, QSFP_DEV | QSFP_OFFSET_SIZE,
511 offset, bp + count, nread);
512 if (ret)
513 break;
514
515 count += nread;
516 addr += nread;
517 }
518
519 if (ret < 0)
520 return ret;
521 return count;
522}
523
524
525
526
527
528int one_qsfp_read(struct hfi1_pportdata *ppd, u32 target, int addr, void *bp,
529 int len)
530{
531 struct hfi1_devdata *dd = ppd->dd;
532 u32 resource = qsfp_resource(dd);
533 int ret;
534
535 ret = acquire_chip_resource(dd, resource, QSFP_WAIT);
536 if (ret)
537 return ret;
538 ret = qsfp_read(ppd, target, addr, bp, len);
539 release_chip_resource(dd, resource);
540
541 return ret;
542}
543
544
545
546
547
548
549
550
551
552
553
554
555
556int refresh_qsfp_cache(struct hfi1_pportdata *ppd, struct qsfp_data *cp)
557{
558 u32 target = ppd->dd->hfi1_id;
559 int ret;
560 unsigned long flags;
561 u8 *cache = &cp->cache[0];
562
563
564 memset(cache, 0, (QSFP_MAX_NUM_PAGES * 128));
565 spin_lock_irqsave(&ppd->qsfp_info.qsfp_lock, flags);
566 ppd->qsfp_info.cache_valid = 0;
567 spin_unlock_irqrestore(&ppd->qsfp_info.qsfp_lock, flags);
568
569 if (!qsfp_mod_present(ppd)) {
570 ret = -ENODEV;
571 goto bail;
572 }
573
574 ret = qsfp_read(ppd, target, 0, cache, QSFP_PAGESIZE);
575 if (ret != QSFP_PAGESIZE) {
576 dd_dev_info(ppd->dd,
577 "%s: Page 0 read failed, expected %d, got %d\n",
578 __func__, QSFP_PAGESIZE, ret);
579 goto bail;
580 }
581
582
583 if (!(cache[2] & 4)) {
584
585 if ((cache[195] & 0xC0) == 0xC0) {
586
587 ret = qsfp_read(ppd, target, 384, cache + 256, 128);
588 if (ret <= 0 || ret != 128) {
589 dd_dev_info(ppd->dd, "%s failed\n", __func__);
590 goto bail;
591 }
592 ret = qsfp_read(ppd, target, 640, cache + 384, 128);
593 if (ret <= 0 || ret != 128) {
594 dd_dev_info(ppd->dd, "%s failed\n", __func__);
595 goto bail;
596 }
597 ret = qsfp_read(ppd, target, 896, cache + 512, 128);
598 if (ret <= 0 || ret != 128) {
599 dd_dev_info(ppd->dd, "%s failed\n", __func__);
600 goto bail;
601 }
602 } else if ((cache[195] & 0x80) == 0x80) {
603
604 ret = qsfp_read(ppd, target, 640, cache + 384, 128);
605 if (ret <= 0 || ret != 128) {
606 dd_dev_info(ppd->dd, "%s failed\n", __func__);
607 goto bail;
608 }
609 ret = qsfp_read(ppd, target, 896, cache + 512, 128);
610 if (ret <= 0 || ret != 128) {
611 dd_dev_info(ppd->dd, "%s failed\n", __func__);
612 goto bail;
613 }
614 } else if ((cache[195] & 0x40) == 0x40) {
615
616 ret = qsfp_read(ppd, target, 384, cache + 256, 128);
617 if (ret <= 0 || ret != 128) {
618 dd_dev_info(ppd->dd, "%s failed\n", __func__);
619 goto bail;
620 }
621 ret = qsfp_read(ppd, target, 896, cache + 512, 128);
622 if (ret <= 0 || ret != 128) {
623 dd_dev_info(ppd->dd, "%s failed\n", __func__);
624 goto bail;
625 }
626 } else {
627
628 ret = qsfp_read(ppd, target, 896, cache + 512, 128);
629 if (ret <= 0 || ret != 128) {
630 dd_dev_info(ppd->dd, "%s failed\n", __func__);
631 goto bail;
632 }
633 }
634 }
635
636 spin_lock_irqsave(&ppd->qsfp_info.qsfp_lock, flags);
637 ppd->qsfp_info.cache_valid = 1;
638 ppd->qsfp_info.cache_refresh_required = 0;
639 spin_unlock_irqrestore(&ppd->qsfp_info.qsfp_lock, flags);
640
641 return 0;
642
643bail:
644 memset(cache, 0, (QSFP_MAX_NUM_PAGES * 128));
645 return ret;
646}
647
648const char * const hfi1_qsfp_devtech[16] = {
649 "850nm VCSEL", "1310nm VCSEL", "1550nm VCSEL", "1310nm FP",
650 "1310nm DFB", "1550nm DFB", "1310nm EML", "1550nm EML",
651 "Cu Misc", "1490nm DFB", "Cu NoEq", "Cu Eq",
652 "Undef", "Cu Active BothEq", "Cu FarEq", "Cu NearEq"
653};
654
655#define QSFP_DUMP_CHUNK 16
656#define QSFP_DEFAULT_HDR_CNT 224
657
658#define QSFP_PWR(pbyte) (((pbyte) >> 6) & 3)
659#define QSFP_HIGH_PWR(pbyte) ((pbyte) & 3)
660
661#define QSFP_HIGH_PWR_UNUSED 0
662
663
664
665
666
667int get_qsfp_power_class(u8 power_byte)
668{
669 if (QSFP_HIGH_PWR(power_byte) == QSFP_HIGH_PWR_UNUSED)
670
671 return (QSFP_PWR(power_byte) + 1);
672
673
674
675
676
677
678 return (QSFP_HIGH_PWR(power_byte) + 4);
679}
680
681int qsfp_mod_present(struct hfi1_pportdata *ppd)
682{
683 struct hfi1_devdata *dd = ppd->dd;
684 u64 reg;
685
686 reg = read_csr(dd, dd->hfi1_id ? ASIC_QSFP2_IN : ASIC_QSFP1_IN);
687 return !(reg & QSFP_HFI0_MODPRST_N);
688}
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705int get_cable_info(struct hfi1_devdata *dd, u32 port_num, u32 addr, u32 len,
706 u8 *data)
707{
708 struct hfi1_pportdata *ppd;
709 u32 excess_len = len;
710 int ret = 0, offset = 0;
711
712 if (port_num > dd->num_pports || port_num < 1) {
713 dd_dev_info(dd, "%s: Invalid port number %d\n",
714 __func__, port_num);
715 ret = -EINVAL;
716 goto set_zeroes;
717 }
718
719 ppd = dd->pport + (port_num - 1);
720 if (!qsfp_mod_present(ppd)) {
721 ret = -ENODEV;
722 goto set_zeroes;
723 }
724
725 if (!ppd->qsfp_info.cache_valid) {
726 ret = -EINVAL;
727 goto set_zeroes;
728 }
729
730 if (addr >= (QSFP_MAX_NUM_PAGES * 128)) {
731 ret = -ERANGE;
732 goto set_zeroes;
733 }
734
735 if ((addr + len) > (QSFP_MAX_NUM_PAGES * 128)) {
736 excess_len = (addr + len) - (QSFP_MAX_NUM_PAGES * 128);
737 memcpy(data, &ppd->qsfp_info.cache[addr], (len - excess_len));
738 data += (len - excess_len);
739 goto set_zeroes;
740 }
741
742 memcpy(data, &ppd->qsfp_info.cache[addr], len);
743
744 if (addr <= QSFP_MONITOR_VAL_END &&
745 (addr + len) >= QSFP_MONITOR_VAL_START) {
746
747 if (addr < QSFP_MONITOR_VAL_START) {
748 if (addr + len <= QSFP_MONITOR_VAL_END)
749 len = addr + len - QSFP_MONITOR_VAL_START;
750 else
751 len = QSFP_MONITOR_RANGE;
752 offset = QSFP_MONITOR_VAL_START - addr;
753 addr = QSFP_MONITOR_VAL_START;
754 } else if (addr == QSFP_MONITOR_VAL_START) {
755 offset = 0;
756 if (addr + len > QSFP_MONITOR_VAL_END)
757 len = QSFP_MONITOR_RANGE;
758 } else {
759 offset = 0;
760 if (addr + len > QSFP_MONITOR_VAL_END)
761 len = QSFP_MONITOR_VAL_END - addr + 1;
762 }
763
764 ret = one_qsfp_read(ppd, dd->hfi1_id, addr, data + offset, len);
765 if (ret != len) {
766 ret = -EAGAIN;
767 goto set_zeroes;
768 }
769 }
770
771 return 0;
772
773set_zeroes:
774 memset(data, 0, excess_len);
775 return ret;
776}
777
778static const char *pwr_codes[8] = {"N/AW",
779 "1.5W",
780 "2.0W",
781 "2.5W",
782 "3.5W",
783 "4.0W",
784 "4.5W",
785 "5.0W"
786 };
787
788int qsfp_dump(struct hfi1_pportdata *ppd, char *buf, int len)
789{
790 u8 *cache = &ppd->qsfp_info.cache[0];
791 u8 bin_buff[QSFP_DUMP_CHUNK];
792 char lenstr[6];
793 int sofar;
794 int bidx = 0;
795 u8 *atten = &cache[QSFP_ATTEN_OFFS];
796 u8 *vendor_oui = &cache[QSFP_VOUI_OFFS];
797 u8 power_byte = 0;
798
799 sofar = 0;
800 lenstr[0] = ' ';
801 lenstr[1] = '\0';
802
803 if (ppd->qsfp_info.cache_valid) {
804 if (QSFP_IS_CU(cache[QSFP_MOD_TECH_OFFS]))
805 snprintf(lenstr, sizeof(lenstr), "%dM ",
806 cache[QSFP_MOD_LEN_OFFS]);
807
808 power_byte = cache[QSFP_MOD_PWR_OFFS];
809 sofar += scnprintf(buf + sofar, len - sofar, "PWR:%.3sW\n",
810 pwr_codes[get_qsfp_power_class(power_byte)]);
811
812 sofar += scnprintf(buf + sofar, len - sofar, "TECH:%s%s\n",
813 lenstr,
814 hfi1_qsfp_devtech[(cache[QSFP_MOD_TECH_OFFS]) >> 4]);
815
816 sofar += scnprintf(buf + sofar, len - sofar, "Vendor:%.*s\n",
817 QSFP_VEND_LEN, &cache[QSFP_VEND_OFFS]);
818
819 sofar += scnprintf(buf + sofar, len - sofar, "OUI:%06X\n",
820 QSFP_OUI(vendor_oui));
821
822 sofar += scnprintf(buf + sofar, len - sofar, "Part#:%.*s\n",
823 QSFP_PN_LEN, &cache[QSFP_PN_OFFS]);
824
825 sofar += scnprintf(buf + sofar, len - sofar, "Rev:%.*s\n",
826 QSFP_REV_LEN, &cache[QSFP_REV_OFFS]);
827
828 if (QSFP_IS_CU(cache[QSFP_MOD_TECH_OFFS]))
829 sofar += scnprintf(buf + sofar, len - sofar,
830 "Atten:%d, %d\n",
831 QSFP_ATTEN_SDR(atten),
832 QSFP_ATTEN_DDR(atten));
833
834 sofar += scnprintf(buf + sofar, len - sofar, "Serial:%.*s\n",
835 QSFP_SN_LEN, &cache[QSFP_SN_OFFS]);
836
837 sofar += scnprintf(buf + sofar, len - sofar, "Date:%.*s\n",
838 QSFP_DATE_LEN, &cache[QSFP_DATE_OFFS]);
839
840 sofar += scnprintf(buf + sofar, len - sofar, "Lot:%.*s\n",
841 QSFP_LOT_LEN, &cache[QSFP_LOT_OFFS]);
842
843 while (bidx < QSFP_DEFAULT_HDR_CNT) {
844 int iidx;
845
846 memcpy(bin_buff, &cache[bidx], QSFP_DUMP_CHUNK);
847 for (iidx = 0; iidx < QSFP_DUMP_CHUNK; ++iidx) {
848 sofar += scnprintf(buf + sofar, len - sofar,
849 " %02X", bin_buff[iidx]);
850 }
851 sofar += scnprintf(buf + sofar, len - sofar, "\n");
852 bidx += QSFP_DUMP_CHUNK;
853 }
854 }
855 return sofar;
856}
857