Merge remote-tracking branches 'asoc/fix/rcar', 'asoc/fix/rt5670' and 'asoc/fix/wm894...
[deliverable/linux.git] / drivers / infiniband / hw / hfi1 / qsfp.c
CommitLineData
77241056 1/*
05d6ac1d 2 * Copyright(c) 2015, 2016 Intel Corporation.
77241056
MM
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 *
77241056
MM
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 *
77241056
MM
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/*
765a6fac 62 * Raw i2c write. No set-up or lock checking.
77241056
MM
63 */
64static 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
77241056
MM
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
765a6fac
DL
91/*
92 * Caller must hold the i2c chain resource.
93 */
77241056
MM
94int i2c_write(struct hfi1_pportdata *ppd, u32 target, int i2c_addr, int offset,
95 void *bp, int len)
96{
77241056
MM
97 int ret;
98
f9c82a0b 99 if (!check_chip_resource(ppd->dd, i2c_target(target), __func__))
765a6fac 100 return -EACCES;
f1bf2963
DL
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,
354d9c95
DL
106 "I2C chain %d write interface reset failed\n",
107 target);
765a6fac 108 return ret;
77241056
MM
109 }
110
765a6fac 111 return __i2c_write(ppd, target, i2c_addr, offset, bp, len);
77241056
MM
112}
113
114/*
765a6fac 115 * Raw i2c read. No set-up or lock checking.
77241056
MM
116 */
117static 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;
354d9c95 122 int orig_offset = offset;
77241056 123
77241056
MM
124 cnt = 0;
125 while (cnt < len) {
126 int rlen = len - cnt;
127
128 ret = hfi1_twsi_blk_rd(dd, target, i2c_addr, offset,
354d9c95 129 bp + cnt, rlen);
77241056
MM
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
144exit:
354d9c95 145 if (ret < 0) {
77241056 146 hfi1_dev_porterr(dd, ppd->port,
354d9c95
DL
147 "I2C chain %d read failed, addr 0x%x, offset 0x%x, len %d\n",
148 target, i2c_addr, orig_offset, len);
149 }
77241056
MM
150
151 /* Must wait min 20us between qsfp i2c transactions */
152 udelay(20);
153
154 return ret;
155}
156
765a6fac
DL
157/*
158 * Caller must hold the i2c chain resource.
159 */
77241056
MM
160int i2c_read(struct hfi1_pportdata *ppd, u32 target, int i2c_addr, int offset,
161 void *bp, int len)
162{
77241056
MM
163 int ret;
164
f9c82a0b 165 if (!check_chip_resource(ppd->dd, i2c_target(target), __func__))
765a6fac 166 return -EACCES;
f1bf2963
DL
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,
354d9c95
DL
172 "I2C chain %d read interface reset failed\n",
173 target);
765a6fac 174 return ret;
77241056
MM
175 }
176
765a6fac 177 return __i2c_read(ppd, target, i2c_addr, offset, bp, len);
77241056
MM
178}
179
c7cb7635
MM
180/*
181 * Write page n, offset m of QSFP memory as defined by SFF 8636
e8aa284b 182 * by writing @addr = ((256 * n) + m)
765a6fac
DL
183 *
184 * Caller must hold the i2c chain resource.
c7cb7635 185 */
77241056
MM
186int 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
f9c82a0b 195 if (!check_chip_resource(ppd->dd, i2c_target(target), __func__))
765a6fac 196 return -EACCES;
77241056 197
f1bf2963
DL
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,
354d9c95
DL
202 "QSFP chain %d write interface reset failed\n",
203 target);
cfe3e656 204 return ret;
f1bf2963
DL
205 }
206
77241056
MM
207 while (count < len) {
208 /*
16733b88 209 * Set the qsfp page based on a zero-based address
77241056
MM
210 * and a page size of QSFP_PAGESIZE bytes.
211 */
212 page = (u8)(addr / QSFP_PAGESIZE);
213
f1bf2963
DL
214 ret = __i2c_write(ppd, target, QSFP_DEV | QSFP_OFFSET_SIZE,
215 QSFP_PAGE_SELECT_BYTE_OFFS, &page, 1);
77241056 216 if (ret != 1) {
354d9c95
DL
217 hfi1_dev_porterr(ppd->dd, ppd->port,
218 "QSFP chain %d can't write QSFP_PAGE_SELECT_BYTE: %d\n",
219 target, ret);
77241056
MM
220 ret = -EIO;
221 break;
222 }
223
77241056
MM
224 offset = addr % QSFP_PAGESIZE;
225 nwrite = len - count;
c7cb7635
MM
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);
77241056 229
f1bf2963
DL
230 ret = __i2c_write(ppd, target, QSFP_DEV | QSFP_OFFSET_SIZE,
231 offset, bp + count, nwrite);
c7cb7635 232 if (ret <= 0) /* stop on error or nothing written */
77241056
MM
233 break;
234
235 count += ret;
236 addr += ret;
237 }
238
77241056
MM
239 if (ret < 0)
240 return ret;
241 return count;
242}
243
765a6fac
DL
244/*
245 * Perform a stand-alone single QSFP write. Acquire the resource, do the
246 * read, then release the resource.
247 */
248int 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
c7cb7635
MM
264/*
265 * Access page n, offset m of QSFP memory as defined by SFF 8636
e8aa284b 266 * by reading @addr = ((256 * n) + m)
765a6fac
DL
267 *
268 * Caller must hold the i2c chain resource.
c7cb7635 269 */
77241056
MM
270int 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
f9c82a0b 279 if (!check_chip_resource(ppd->dd, i2c_target(target), __func__))
765a6fac 280 return -EACCES;
77241056 281
f1bf2963
DL
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,
354d9c95
DL
286 "QSFP chain %d read interface reset failed\n",
287 target);
cfe3e656 288 return ret;
f1bf2963
DL
289 }
290
77241056
MM
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);
f1bf2963
DL
297 ret = __i2c_write(ppd, target, QSFP_DEV | QSFP_OFFSET_SIZE,
298 QSFP_PAGE_SELECT_BYTE_OFFS, &page, 1);
77241056 299 if (ret != 1) {
354d9c95
DL
300 hfi1_dev_porterr(ppd->dd, ppd->port,
301 "QSFP chain %d can't write QSFP_PAGE_SELECT_BYTE: %d\n",
302 target, ret);
77241056
MM
303 ret = -EIO;
304 break;
305 }
306
77241056
MM
307 offset = addr % QSFP_PAGESIZE;
308 nread = len - count;
c7cb7635
MM
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);
77241056 312
f1bf2963
DL
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);
77241056
MM
317 if (ret <= 0) /* stop on error or nothing read */
318 break;
319
320 count += ret;
321 addr += ret;
322 }
323
77241056
MM
324 if (ret < 0)
325 return ret;
326 return count;
327}
328
765a6fac
DL
329/*
330 * Perform a stand-alone single QSFP read. Acquire the resource, do the
331 * read, then release the resource.
332 */
333int 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
77241056
MM
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.
c7cb7635
MM
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
e4e0e39c
DL
358 *
359 * The caller must be holding the QSFP i2c chain resource.
77241056
MM
360 */
361int 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 */
8638b77f 369 memset(cache, 0, (QSFP_MAX_NUM_PAGES * 128));
c7cb7635
MM
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
77241056
MM
374 if (!qsfp_mod_present(ppd)) {
375 ret = -ENODEV;
e4e0e39c 376 goto bail;
77241056
MM
377 }
378
c7cb7635
MM
379 ret = qsfp_read(ppd, target, 0, cache, QSFP_PAGESIZE);
380 if (ret != QSFP_PAGESIZE) {
77241056 381 dd_dev_info(ppd->dd,
c7cb7635
MM
382 "%s: Page 0 read failed, expected %d, got %d\n",
383 __func__, QSFP_PAGESIZE, ret);
77241056
MM
384 goto bail;
385 }
386
77241056
MM
387 /* Is paging enabled? */
388 if (!(cache[2] & 4)) {
77241056
MM
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) {
76ef8c07 394 dd_dev_info(ppd->dd, "%s failed\n", __func__);
77241056
MM
395 goto bail;
396 }
397 ret = qsfp_read(ppd, target, 640, cache + 384, 128);
398 if (ret <= 0 || ret != 128) {
76ef8c07 399 dd_dev_info(ppd->dd, "%s failed\n", __func__);
77241056
MM
400 goto bail;
401 }
402 ret = qsfp_read(ppd, target, 896, cache + 512, 128);
403 if (ret <= 0 || ret != 128) {
76ef8c07 404 dd_dev_info(ppd->dd, "%s failed\n", __func__);
77241056
MM
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) {
76ef8c07 411 dd_dev_info(ppd->dd, "%s failed\n", __func__);
77241056
MM
412 goto bail;
413 }
414 ret = qsfp_read(ppd, target, 896, cache + 512, 128);
415 if (ret <= 0 || ret != 128) {
76ef8c07 416 dd_dev_info(ppd->dd, "%s failed\n", __func__);
77241056
MM
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) {
76ef8c07 423 dd_dev_info(ppd->dd, "%s failed\n", __func__);
77241056
MM
424 goto bail;
425 }
426 ret = qsfp_read(ppd, target, 896, cache + 512, 128);
427 if (ret <= 0 || ret != 128) {
76ef8c07 428 dd_dev_info(ppd->dd, "%s failed\n", __func__);
77241056
MM
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) {
76ef8c07 435 dd_dev_info(ppd->dd, "%s failed\n", __func__);
77241056
MM
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
448bail:
8638b77f 449 memset(cache, 0, (QSFP_MAX_NUM_PAGES * 128));
77241056
MM
450 return ret;
451}
452
453const 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
145dd2b3
EH
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 */
472int 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}
77241056
MM
485
486int qsfp_mod_present(struct hfi1_pportdata *ppd)
487{
3c2f85b8
EH
488 struct hfi1_devdata *dd = ppd->dd;
489 u64 reg;
77241056 490
3c2f85b8
EH
491 reg = read_csr(dd, dd->hfi1_id ? ASIC_QSFP2_IN : ASIC_QSFP1_IN);
492 return !(reg & QSFP_HFI0_MODPRST_N);
77241056
MM
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 */
510int 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",
17fb4f29 519 __func__, port_num);
77241056
MM
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
550set_zeroes:
551 memset(data, 0, excess_len);
552 return ret;
553}
554
145dd2b3
EH
555static 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
77241056
MM
565int 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];
463f8e72 570 int sofar;
77241056
MM
571 int bidx = 0;
572 u8 *atten = &cache[QSFP_ATTEN_OFFS];
573 u8 *vendor_oui = &cache[QSFP_VOUI_OFFS];
145dd2b3 574 u8 power_byte = 0;
77241056
MM
575
576 sofar = 0;
577 lenstr[0] = ' ';
578 lenstr[1] = '\0';
579
580 if (ppd->qsfp_info.cache_valid) {
77241056 581 if (QSFP_IS_CU(cache[QSFP_MOD_TECH_OFFS]))
c078f0dd
TS
582 snprintf(lenstr, sizeof(lenstr), "%dM ",
583 cache[QSFP_MOD_LEN_OFFS]);
77241056 584
145dd2b3 585 power_byte = cache[QSFP_MOD_PWR_OFFS];
77241056 586 sofar += scnprintf(buf + sofar, len - sofar, "PWR:%.3sW\n",
145dd2b3 587 pwr_codes[get_qsfp_power_class(power_byte)]);
77241056
MM
588
589 sofar += scnprintf(buf + sofar, len - sofar, "TECH:%s%s\n",
590 lenstr,
591 hfi1_qsfp_devtech[(cache[QSFP_MOD_TECH_OFFS]) >> 4]);
592
593 sofar += scnprintf(buf + sofar, len - sofar, "Vendor:%.*s\n",
594 QSFP_VEND_LEN, &cache[QSFP_VEND_OFFS]);
595
596 sofar += scnprintf(buf + sofar, len - sofar, "OUI:%06X\n",
597 QSFP_OUI(vendor_oui));
598
599 sofar += scnprintf(buf + sofar, len - sofar, "Part#:%.*s\n",
600 QSFP_PN_LEN, &cache[QSFP_PN_OFFS]);
601
602 sofar += scnprintf(buf + sofar, len - sofar, "Rev:%.*s\n",
603 QSFP_REV_LEN, &cache[QSFP_REV_OFFS]);
604
605 if (QSFP_IS_CU(cache[QSFP_MOD_TECH_OFFS]))
606 sofar += scnprintf(buf + sofar, len - sofar,
607 "Atten:%d, %d\n",
608 QSFP_ATTEN_SDR(atten),
609 QSFP_ATTEN_DDR(atten));
610
611 sofar += scnprintf(buf + sofar, len - sofar, "Serial:%.*s\n",
612 QSFP_SN_LEN, &cache[QSFP_SN_OFFS]);
613
614 sofar += scnprintf(buf + sofar, len - sofar, "Date:%.*s\n",
615 QSFP_DATE_LEN, &cache[QSFP_DATE_OFFS]);
616
617 sofar += scnprintf(buf + sofar, len - sofar, "Lot:%.*s\n",
618 QSFP_LOT_LEN, &cache[QSFP_LOT_OFFS]);
619
620 while (bidx < QSFP_DEFAULT_HDR_CNT) {
621 int iidx;
622
623 memcpy(bin_buff, &cache[bidx], QSFP_DUMP_CHUNK);
624 for (iidx = 0; iidx < QSFP_DUMP_CHUNK; ++iidx) {
8638b77f 625 sofar += scnprintf(buf + sofar, len - sofar,
77241056
MM
626 " %02X", bin_buff[iidx]);
627 }
628 sofar += scnprintf(buf + sofar, len - sofar, "\n");
629 bidx += QSFP_DUMP_CHUNK;
630 }
631 }
463f8e72 632 return sofar;
77241056 633}
This page took 0.174288 seconds and 5 git commands to generate.