xref: /linux/drivers/infiniband/hw/hfi1/qsfp.c (revision 0883c2c06fb5bcf5b9e008270827e63c09a88c1e)
1 /*
2  * Copyright(c) 2015, 2016 Intel Corporation.
3  *
4  * This file is provided under a dual BSD/GPLv2 license.  When using or
5  * redistributing this file, you may do so under either license.
6  *
7  * GPL LICENSE SUMMARY
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of version 2 of the GNU General Public License as
11  * published by the Free Software Foundation.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  *
18  * BSD LICENSE
19  *
20  * Redistribution and use in source and binary forms, with or without
21  * modification, are permitted provided that the following conditions
22  * are met:
23  *
24  *  - Redistributions of source code must retain the above copyright
25  *    notice, this list of conditions and the following disclaimer.
26  *  - Redistributions in binary form must reproduce the above copyright
27  *    notice, this list of conditions and the following disclaimer in
28  *    the documentation and/or other materials provided with the
29  *    distribution.
30  *  - Neither the name of Intel Corporation nor the names of its
31  *    contributors may be used to endorse or promote products derived
32  *    from this software without specific prior written permission.
33  *
34  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
35  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
36  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
37  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
38  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
39  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
40  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
41  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
42  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
43  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
44  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45  *
46  */
47 
48 #include <linux/delay.h>
49 #include <linux/pci.h>
50 #include <linux/vmalloc.h>
51 
52 #include "hfi.h"
53 #include "twsi.h"
54 
55 /*
56  * QSFP support for hfi driver, using "Two Wire Serial Interface" driver
57  * in twsi.c
58  */
59 #define I2C_MAX_RETRY 4
60 
61 /*
62  * Raw i2c write.  No set-up or lock checking.
63  */
64 static int __i2c_write(struct hfi1_pportdata *ppd, u32 target, int i2c_addr,
65 		       int offset, void *bp, int len)
66 {
67 	struct hfi1_devdata *dd = ppd->dd;
68 	int ret, cnt;
69 	u8 *buff = bp;
70 
71 	cnt = 0;
72 	while (cnt < len) {
73 		int wlen = len - cnt;
74 
75 		ret = hfi1_twsi_blk_wr(dd, target, i2c_addr, offset,
76 				       buff + cnt, wlen);
77 		if (ret) {
78 			/* hfi1_twsi_blk_wr() 1 for error, else 0 */
79 			return -EIO;
80 		}
81 		offset += wlen;
82 		cnt += wlen;
83 	}
84 
85 	/* Must wait min 20us between qsfp i2c transactions */
86 	udelay(20);
87 
88 	return cnt;
89 }
90 
91 /*
92  * Caller must hold the i2c chain resource.
93  */
94 int i2c_write(struct hfi1_pportdata *ppd, u32 target, int i2c_addr, int offset,
95 	      void *bp, int len)
96 {
97 	int ret;
98 
99 	if (!check_chip_resource(ppd->dd, i2c_target(target), __func__))
100 		return -EACCES;
101 
102 	/* make sure the TWSI bus is in a sane state */
103 	ret = hfi1_twsi_reset(ppd->dd, target);
104 	if (ret) {
105 		hfi1_dev_porterr(ppd->dd, ppd->port,
106 				 "I2C chain %d write interface reset failed\n",
107 				 target);
108 		return ret;
109 	}
110 
111 	return __i2c_write(ppd, target, i2c_addr, offset, bp, len);
112 }
113 
114 /*
115  * Raw i2c read.  No set-up or lock checking.
116  */
117 static int __i2c_read(struct hfi1_pportdata *ppd, u32 target, int i2c_addr,
118 		      int offset, void *bp, int len)
119 {
120 	struct hfi1_devdata *dd = ppd->dd;
121 	int ret, cnt, pass = 0;
122 	int orig_offset = offset;
123 
124 	cnt = 0;
125 	while (cnt < len) {
126 		int rlen = len - cnt;
127 
128 		ret = hfi1_twsi_blk_rd(dd, target, i2c_addr, offset,
129 				       bp + cnt, rlen);
130 		/* Some QSFP's fail first try. Retry as experiment */
131 		if (ret && cnt == 0 && ++pass < I2C_MAX_RETRY)
132 			continue;
133 		if (ret) {
134 			/* hfi1_twsi_blk_rd() 1 for error, else 0 */
135 			ret = -EIO;
136 			goto exit;
137 		}
138 		offset += rlen;
139 		cnt += rlen;
140 	}
141 
142 	ret = cnt;
143 
144 exit:
145 	if (ret < 0) {
146 		hfi1_dev_porterr(dd, ppd->port,
147 				 "I2C chain %d read failed, addr 0x%x, offset 0x%x, len %d\n",
148 				 target, i2c_addr, orig_offset, len);
149 	}
150 
151 	/* Must wait min 20us between qsfp i2c transactions */
152 	udelay(20);
153 
154 	return ret;
155 }
156 
157 /*
158  * Caller must hold the i2c chain resource.
159  */
160 int i2c_read(struct hfi1_pportdata *ppd, u32 target, int i2c_addr, int offset,
161 	     void *bp, int len)
162 {
163 	int ret;
164 
165 	if (!check_chip_resource(ppd->dd, i2c_target(target), __func__))
166 		return -EACCES;
167 
168 	/* make sure the TWSI bus is in a sane state */
169 	ret = hfi1_twsi_reset(ppd->dd, target);
170 	if (ret) {
171 		hfi1_dev_porterr(ppd->dd, ppd->port,
172 				 "I2C chain %d read interface reset failed\n",
173 				 target);
174 		return ret;
175 	}
176 
177 	return __i2c_read(ppd, target, i2c_addr, offset, bp, len);
178 }
179 
180 /*
181  * Write page n, offset m of QSFP memory as defined by SFF 8636
182  * by writing @addr = ((256 * n) + m)
183  *
184  * Caller must hold the i2c chain resource.
185  */
186 int qsfp_write(struct hfi1_pportdata *ppd, u32 target, int addr, void *bp,
187 	       int len)
188 {
189 	int count = 0;
190 	int offset;
191 	int nwrite;
192 	int ret;
193 	u8 page;
194 
195 	if (!check_chip_resource(ppd->dd, i2c_target(target), __func__))
196 		return -EACCES;
197 
198 	/* make sure the TWSI bus is in a sane state */
199 	ret = hfi1_twsi_reset(ppd->dd, target);
200 	if (ret) {
201 		hfi1_dev_porterr(ppd->dd, ppd->port,
202 				 "QSFP chain %d write interface reset failed\n",
203 				 target);
204 		return ret;
205 	}
206 
207 	while (count < len) {
208 		/*
209 		 * Set the qsfp page based on a zero-based address
210 		 * and a page size of QSFP_PAGESIZE bytes.
211 		 */
212 		page = (u8)(addr / QSFP_PAGESIZE);
213 
214 		ret = __i2c_write(ppd, target, QSFP_DEV | QSFP_OFFSET_SIZE,
215 				  QSFP_PAGE_SELECT_BYTE_OFFS, &page, 1);
216 		if (ret != 1) {
217 			hfi1_dev_porterr(ppd->dd, ppd->port,
218 					 "QSFP chain %d can't write QSFP_PAGE_SELECT_BYTE: %d\n",
219 					 target, ret);
220 			ret = -EIO;
221 			break;
222 		}
223 
224 		offset = addr % QSFP_PAGESIZE;
225 		nwrite = len - count;
226 		/* truncate write to boundary if crossing boundary */
227 		if (((addr % QSFP_RW_BOUNDARY) + nwrite) > QSFP_RW_BOUNDARY)
228 			nwrite = QSFP_RW_BOUNDARY - (addr % QSFP_RW_BOUNDARY);
229 
230 		ret = __i2c_write(ppd, target, QSFP_DEV | QSFP_OFFSET_SIZE,
231 				  offset, bp + count, nwrite);
232 		if (ret <= 0)	/* stop on error or nothing written */
233 			break;
234 
235 		count += ret;
236 		addr += ret;
237 	}
238 
239 	if (ret < 0)
240 		return ret;
241 	return count;
242 }
243 
244 /*
245  * Perform a stand-alone single QSFP write.  Acquire the resource, do the
246  * read, then release the resource.
247  */
248 int one_qsfp_write(struct hfi1_pportdata *ppd, u32 target, int addr, void *bp,
249 		   int len)
250 {
251 	struct hfi1_devdata *dd = ppd->dd;
252 	u32 resource = qsfp_resource(dd);
253 	int ret;
254 
255 	ret = acquire_chip_resource(dd, resource, QSFP_WAIT);
256 	if (ret)
257 		return ret;
258 	ret = qsfp_write(ppd, target, addr, bp, len);
259 	release_chip_resource(dd, resource);
260 
261 	return ret;
262 }
263 
264 /*
265  * Access page n, offset m of QSFP memory as defined by SFF 8636
266  * by reading @addr = ((256 * n) + m)
267  *
268  * Caller must hold the i2c chain resource.
269  */
270 int qsfp_read(struct hfi1_pportdata *ppd, u32 target, int addr, void *bp,
271 	      int len)
272 {
273 	int count = 0;
274 	int offset;
275 	int nread;
276 	int ret;
277 	u8 page;
278 
279 	if (!check_chip_resource(ppd->dd, i2c_target(target), __func__))
280 		return -EACCES;
281 
282 	/* make sure the TWSI bus is in a sane state */
283 	ret = hfi1_twsi_reset(ppd->dd, target);
284 	if (ret) {
285 		hfi1_dev_porterr(ppd->dd, ppd->port,
286 				 "QSFP chain %d read interface reset failed\n",
287 				 target);
288 		return ret;
289 	}
290 
291 	while (count < len) {
292 		/*
293 		 * Set the qsfp page based on a zero-based address
294 		 * and a page size of QSFP_PAGESIZE bytes.
295 		 */
296 		page = (u8)(addr / QSFP_PAGESIZE);
297 		ret = __i2c_write(ppd, target, QSFP_DEV | QSFP_OFFSET_SIZE,
298 				  QSFP_PAGE_SELECT_BYTE_OFFS, &page, 1);
299 		if (ret != 1) {
300 			hfi1_dev_porterr(ppd->dd, ppd->port,
301 					 "QSFP chain %d can't write QSFP_PAGE_SELECT_BYTE: %d\n",
302 					 target, ret);
303 			ret = -EIO;
304 			break;
305 		}
306 
307 		offset = addr % QSFP_PAGESIZE;
308 		nread = len - count;
309 		/* truncate read to boundary if crossing boundary */
310 		if (((addr % QSFP_RW_BOUNDARY) + nread) > QSFP_RW_BOUNDARY)
311 			nread = QSFP_RW_BOUNDARY - (addr % QSFP_RW_BOUNDARY);
312 
313 		/* QSFPs require a 5-10msec delay after write operations */
314 		mdelay(5);
315 		ret = __i2c_read(ppd, target, QSFP_DEV | QSFP_OFFSET_SIZE,
316 				 offset, bp + count, nread);
317 		if (ret <= 0)	/* stop on error or nothing read */
318 			break;
319 
320 		count += ret;
321 		addr += ret;
322 	}
323 
324 	if (ret < 0)
325 		return ret;
326 	return count;
327 }
328 
329 /*
330  * Perform a stand-alone single QSFP read.  Acquire the resource, do the
331  * read, then release the resource.
332  */
333 int one_qsfp_read(struct hfi1_pportdata *ppd, u32 target, int addr, void *bp,
334 		  int len)
335 {
336 	struct hfi1_devdata *dd = ppd->dd;
337 	u32 resource = qsfp_resource(dd);
338 	int ret;
339 
340 	ret = acquire_chip_resource(dd, resource, QSFP_WAIT);
341 	if (ret)
342 		return ret;
343 	ret = qsfp_read(ppd, target, addr, bp, len);
344 	release_chip_resource(dd, resource);
345 
346 	return ret;
347 }
348 
349 /*
350  * This function caches the QSFP memory range in 128 byte chunks.
351  * As an example, the next byte after address 255 is byte 128 from
352  * upper page 01H (if existing) rather than byte 0 from lower page 00H.
353  * Access page n, offset m of QSFP memory as defined by SFF 8636
354  * in the cache by reading byte ((128 * n) + m)
355  * The calls to qsfp_{read,write} in this function correctly handle the
356  * address map difference between this mapping and the mapping implemented
357  * by those functions
358  *
359  * The caller must be holding the QSFP i2c chain resource.
360  */
361 int refresh_qsfp_cache(struct hfi1_pportdata *ppd, struct qsfp_data *cp)
362 {
363 	u32 target = ppd->dd->hfi1_id;
364 	int ret;
365 	unsigned long flags;
366 	u8 *cache = &cp->cache[0];
367 
368 	/* ensure sane contents on invalid reads, for cable swaps */
369 	memset(cache, 0, (QSFP_MAX_NUM_PAGES * 128));
370 	spin_lock_irqsave(&ppd->qsfp_info.qsfp_lock, flags);
371 	ppd->qsfp_info.cache_valid = 0;
372 	spin_unlock_irqrestore(&ppd->qsfp_info.qsfp_lock, flags);
373 
374 	if (!qsfp_mod_present(ppd)) {
375 		ret = -ENODEV;
376 		goto bail;
377 	}
378 
379 	ret = qsfp_read(ppd, target, 0, cache, QSFP_PAGESIZE);
380 	if (ret != QSFP_PAGESIZE) {
381 		dd_dev_info(ppd->dd,
382 			    "%s: Page 0 read failed, expected %d, got %d\n",
383 			    __func__, QSFP_PAGESIZE, ret);
384 		goto bail;
385 	}
386 
387 	/* Is paging enabled? */
388 	if (!(cache[2] & 4)) {
389 		/* Paging enabled, page 03 required */
390 		if ((cache[195] & 0xC0) == 0xC0) {
391 			/* all */
392 			ret = qsfp_read(ppd, target, 384, cache + 256, 128);
393 			if (ret <= 0 || ret != 128) {
394 				dd_dev_info(ppd->dd, "%s failed\n", __func__);
395 				goto bail;
396 			}
397 			ret = qsfp_read(ppd, target, 640, cache + 384, 128);
398 			if (ret <= 0 || ret != 128) {
399 				dd_dev_info(ppd->dd, "%s failed\n", __func__);
400 				goto bail;
401 			}
402 			ret = qsfp_read(ppd, target, 896, cache + 512, 128);
403 			if (ret <= 0 || ret != 128) {
404 				dd_dev_info(ppd->dd, "%s failed\n", __func__);
405 				goto bail;
406 			}
407 		} else if ((cache[195] & 0x80) == 0x80) {
408 			/* only page 2 and 3 */
409 			ret = qsfp_read(ppd, target, 640, cache + 384, 128);
410 			if (ret <= 0 || ret != 128) {
411 				dd_dev_info(ppd->dd, "%s failed\n", __func__);
412 				goto bail;
413 			}
414 			ret = qsfp_read(ppd, target, 896, cache + 512, 128);
415 			if (ret <= 0 || ret != 128) {
416 				dd_dev_info(ppd->dd, "%s failed\n", __func__);
417 				goto bail;
418 			}
419 		} else if ((cache[195] & 0x40) == 0x40) {
420 			/* only page 1 and 3 */
421 			ret = qsfp_read(ppd, target, 384, cache + 256, 128);
422 			if (ret <= 0 || ret != 128) {
423 				dd_dev_info(ppd->dd, "%s failed\n", __func__);
424 				goto bail;
425 			}
426 			ret = qsfp_read(ppd, target, 896, cache + 512, 128);
427 			if (ret <= 0 || ret != 128) {
428 				dd_dev_info(ppd->dd, "%s failed\n", __func__);
429 				goto bail;
430 			}
431 		} else {
432 			/* only page 3 */
433 			ret = qsfp_read(ppd, target, 896, cache + 512, 128);
434 			if (ret <= 0 || ret != 128) {
435 				dd_dev_info(ppd->dd, "%s failed\n", __func__);
436 				goto bail;
437 			}
438 		}
439 	}
440 
441 	spin_lock_irqsave(&ppd->qsfp_info.qsfp_lock, flags);
442 	ppd->qsfp_info.cache_valid = 1;
443 	ppd->qsfp_info.cache_refresh_required = 0;
444 	spin_unlock_irqrestore(&ppd->qsfp_info.qsfp_lock, flags);
445 
446 	return 0;
447 
448 bail:
449 	memset(cache, 0, (QSFP_MAX_NUM_PAGES * 128));
450 	return ret;
451 }
452 
453 const char * const hfi1_qsfp_devtech[16] = {
454 	"850nm VCSEL", "1310nm VCSEL", "1550nm VCSEL", "1310nm FP",
455 	"1310nm DFB", "1550nm DFB", "1310nm EML", "1550nm EML",
456 	"Cu Misc", "1490nm DFB", "Cu NoEq", "Cu Eq",
457 	"Undef", "Cu Active BothEq", "Cu FarEq", "Cu NearEq"
458 };
459 
460 #define QSFP_DUMP_CHUNK 16 /* Holds longest string */
461 #define QSFP_DEFAULT_HDR_CNT 224
462 
463 #define QSFP_PWR(pbyte) (((pbyte) >> 6) & 3)
464 #define QSFP_HIGH_PWR(pbyte) ((pbyte) & 3)
465 /* For use with QSFP_HIGH_PWR macro */
466 #define QSFP_HIGH_PWR_UNUSED	0 /* Bits [1:0] = 00 implies low power module */
467 
468 /*
469  * Takes power class byte [Page 00 Byte 129] in SFF 8636
470  * Returns power class as integer (1 through 7, per SFF 8636 rev 2.4)
471  */
472 int get_qsfp_power_class(u8 power_byte)
473 {
474 	if (QSFP_HIGH_PWR(power_byte) == QSFP_HIGH_PWR_UNUSED)
475 		/* power classes count from 1, their bit encodings from 0 */
476 		return (QSFP_PWR(power_byte) + 1);
477 	/*
478 	 * 00 in the high power classes stands for unused, bringing
479 	 * balance to the off-by-1 offset above, we add 4 here to
480 	 * account for the difference between the low and high power
481 	 * groups
482 	 */
483 	return (QSFP_HIGH_PWR(power_byte) + 4);
484 }
485 
486 int qsfp_mod_present(struct hfi1_pportdata *ppd)
487 {
488 	struct hfi1_devdata *dd = ppd->dd;
489 	u64 reg;
490 
491 	reg = read_csr(dd, dd->hfi1_id ? ASIC_QSFP2_IN : ASIC_QSFP1_IN);
492 	return !(reg & QSFP_HFI0_MODPRST_N);
493 }
494 
495 /*
496  * This function maps QSFP memory addresses in 128 byte chunks in the following
497  * fashion per the CableInfo SMA query definition in the IBA 1.3 spec/OPA Gen 1
498  * spec
499  * For addr 000-127, lower page 00h
500  * For addr 128-255, upper page 00h
501  * For addr 256-383, upper page 01h
502  * For addr 384-511, upper page 02h
503  * For addr 512-639, upper page 03h
504  *
505  * For addresses beyond this range, it returns the invalid range of data buffer
506  * set to 0.
507  * For upper pages that are optional, if they are not valid, returns the
508  * particular range of bytes in the data buffer set to 0.
509  */
510 int get_cable_info(struct hfi1_devdata *dd, u32 port_num, u32 addr, u32 len,
511 		   u8 *data)
512 {
513 	struct hfi1_pportdata *ppd;
514 	u32 excess_len = 0;
515 	int ret = 0;
516 
517 	if (port_num > dd->num_pports || port_num < 1) {
518 		dd_dev_info(dd, "%s: Invalid port number %d\n",
519 			    __func__, port_num);
520 		ret = -EINVAL;
521 		goto set_zeroes;
522 	}
523 
524 	ppd = dd->pport + (port_num - 1);
525 	if (!qsfp_mod_present(ppd)) {
526 		ret = -ENODEV;
527 		goto set_zeroes;
528 	}
529 
530 	if (!ppd->qsfp_info.cache_valid) {
531 		ret = -EINVAL;
532 		goto set_zeroes;
533 	}
534 
535 	if (addr >= (QSFP_MAX_NUM_PAGES * 128)) {
536 		ret = -ERANGE;
537 		goto set_zeroes;
538 	}
539 
540 	if ((addr + len) > (QSFP_MAX_NUM_PAGES * 128)) {
541 		excess_len = (addr + len) - (QSFP_MAX_NUM_PAGES * 128);
542 		memcpy(data, &ppd->qsfp_info.cache[addr], (len - excess_len));
543 		data += (len - excess_len);
544 		goto set_zeroes;
545 	}
546 
547 	memcpy(data, &ppd->qsfp_info.cache[addr], len);
548 	return 0;
549 
550 set_zeroes:
551 	memset(data, 0, excess_len);
552 	return ret;
553 }
554 
555 static const char *pwr_codes[8] = {"N/AW",
556 				  "1.5W",
557 				  "2.0W",
558 				  "2.5W",
559 				  "3.5W",
560 				  "4.0W",
561 				  "4.5W",
562 				  "5.0W"
563 				 };
564 
565 int qsfp_dump(struct hfi1_pportdata *ppd, char *buf, int len)
566 {
567 	u8 *cache = &ppd->qsfp_info.cache[0];
568 	u8 bin_buff[QSFP_DUMP_CHUNK];
569 	char lenstr[6];
570 	int sofar;
571 	int bidx = 0;
572 	u8 *atten = &cache[QSFP_ATTEN_OFFS];
573 	u8 *vendor_oui = &cache[QSFP_VOUI_OFFS];
574 	u8 power_byte = 0;
575 
576 	sofar = 0;
577 	lenstr[0] = ' ';
578 	lenstr[1] = '\0';
579 
580 	if (ppd->qsfp_info.cache_valid) {
581 		if (QSFP_IS_CU(cache[QSFP_MOD_TECH_OFFS]))
582 			sprintf(lenstr, "%dM ", cache[QSFP_MOD_LEN_OFFS]);
583 
584 		power_byte = cache[QSFP_MOD_PWR_OFFS];
585 		sofar += scnprintf(buf + sofar, len - sofar, "PWR:%.3sW\n",
586 				pwr_codes[get_qsfp_power_class(power_byte)]);
587 
588 		sofar += scnprintf(buf + sofar, len - sofar, "TECH:%s%s\n",
589 				lenstr,
590 			hfi1_qsfp_devtech[(cache[QSFP_MOD_TECH_OFFS]) >> 4]);
591 
592 		sofar += scnprintf(buf + sofar, len - sofar, "Vendor:%.*s\n",
593 				   QSFP_VEND_LEN, &cache[QSFP_VEND_OFFS]);
594 
595 		sofar += scnprintf(buf + sofar, len - sofar, "OUI:%06X\n",
596 				   QSFP_OUI(vendor_oui));
597 
598 		sofar += scnprintf(buf + sofar, len - sofar, "Part#:%.*s\n",
599 				   QSFP_PN_LEN, &cache[QSFP_PN_OFFS]);
600 
601 		sofar += scnprintf(buf + sofar, len - sofar, "Rev:%.*s\n",
602 				   QSFP_REV_LEN, &cache[QSFP_REV_OFFS]);
603 
604 		if (QSFP_IS_CU(cache[QSFP_MOD_TECH_OFFS]))
605 			sofar += scnprintf(buf + sofar, len - sofar,
606 				"Atten:%d, %d\n",
607 				QSFP_ATTEN_SDR(atten),
608 				QSFP_ATTEN_DDR(atten));
609 
610 		sofar += scnprintf(buf + sofar, len - sofar, "Serial:%.*s\n",
611 				   QSFP_SN_LEN, &cache[QSFP_SN_OFFS]);
612 
613 		sofar += scnprintf(buf + sofar, len - sofar, "Date:%.*s\n",
614 				   QSFP_DATE_LEN, &cache[QSFP_DATE_OFFS]);
615 
616 		sofar += scnprintf(buf + sofar, len - sofar, "Lot:%.*s\n",
617 				   QSFP_LOT_LEN, &cache[QSFP_LOT_OFFS]);
618 
619 		while (bidx < QSFP_DEFAULT_HDR_CNT) {
620 			int iidx;
621 
622 			memcpy(bin_buff, &cache[bidx], QSFP_DUMP_CHUNK);
623 			for (iidx = 0; iidx < QSFP_DUMP_CHUNK; ++iidx) {
624 				sofar += scnprintf(buf + sofar, len - sofar,
625 					" %02X", bin_buff[iidx]);
626 			}
627 			sofar += scnprintf(buf + sofar, len - sofar, "\n");
628 			bidx += QSFP_DUMP_CHUNK;
629 		}
630 	}
631 	return sofar;
632 }
633