xref: /openbmc/linux/drivers/infiniband/hw/qib/qib_qsfp.c (revision dde05cbdf8b1c404344c370fe6e18ff160d6da6a)
1f931551bSRalph Campbell /*
2f931551bSRalph Campbell  * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights reserved.
3f931551bSRalph Campbell  * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
4f931551bSRalph Campbell  *
5f931551bSRalph Campbell  * This software is available to you under a choice of one of two
6f931551bSRalph Campbell  * licenses.  You may choose to be licensed under the terms of the GNU
7f931551bSRalph Campbell  * General Public License (GPL) Version 2, available from the file
8f931551bSRalph Campbell  * COPYING in the main directory of this source tree, or the
9f931551bSRalph Campbell  * OpenIB.org BSD license below:
10f931551bSRalph Campbell  *
11f931551bSRalph Campbell  *     Redistribution and use in source and binary forms, with or
12f931551bSRalph Campbell  *     without modification, are permitted provided that the following
13f931551bSRalph Campbell  *     conditions are met:
14f931551bSRalph Campbell  *
15f931551bSRalph Campbell  *      - Redistributions of source code must retain the above
16f931551bSRalph Campbell  *        copyright notice, this list of conditions and the following
17f931551bSRalph Campbell  *        disclaimer.
18f931551bSRalph Campbell  *
19f931551bSRalph Campbell  *      - Redistributions in binary form must reproduce the above
20f931551bSRalph Campbell  *        copyright notice, this list of conditions and the following
21f931551bSRalph Campbell  *        disclaimer in the documentation and/or other materials
22f931551bSRalph Campbell  *        provided with the distribution.
23f931551bSRalph Campbell  *
24f931551bSRalph Campbell  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25f931551bSRalph Campbell  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26f931551bSRalph Campbell  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27f931551bSRalph Campbell  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28f931551bSRalph Campbell  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29f931551bSRalph Campbell  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30f931551bSRalph Campbell  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31f931551bSRalph Campbell  * SOFTWARE.
32f931551bSRalph Campbell  */
33f931551bSRalph Campbell 
34f931551bSRalph Campbell #include <linux/delay.h>
35f931551bSRalph Campbell #include <linux/pci.h>
36f931551bSRalph Campbell #include <linux/vmalloc.h>
37f931551bSRalph Campbell 
38f931551bSRalph Campbell #include "qib.h"
39f931551bSRalph Campbell #include "qib_qsfp.h"
40f931551bSRalph Campbell 
41f931551bSRalph Campbell /*
42f931551bSRalph Campbell  * QSFP support for ib_qib driver, using "Two Wire Serial Interface" driver
43f931551bSRalph Campbell  * in qib_twsi.c
44f931551bSRalph Campbell  */
45f931551bSRalph Campbell #define QSFP_MAX_RETRY 4
46f931551bSRalph Campbell 
47f931551bSRalph Campbell static int qsfp_read(struct qib_pportdata *ppd, int addr, void *bp, int len)
48f931551bSRalph Campbell {
49f931551bSRalph Campbell 	struct qib_devdata *dd = ppd->dd;
50f931551bSRalph Campbell 	u32 out, mask;
51f931551bSRalph Campbell 	int ret, cnt, pass = 0;
52f931551bSRalph Campbell 	int stuck = 0;
53f931551bSRalph Campbell 	u8 *buff = bp;
54f931551bSRalph Campbell 
55f931551bSRalph Campbell 	ret = mutex_lock_interruptible(&dd->eep_lock);
56f931551bSRalph Campbell 	if (ret)
57f931551bSRalph Campbell 		goto no_unlock;
58f931551bSRalph Campbell 
59f931551bSRalph Campbell 	if (dd->twsi_eeprom_dev == QIB_TWSI_NO_DEV) {
60f931551bSRalph Campbell 		ret = -ENXIO;
61f931551bSRalph Campbell 		goto bail;
62f931551bSRalph Campbell 	}
63f931551bSRalph Campbell 
64f931551bSRalph Campbell 	/*
65f931551bSRalph Campbell 	 * We presume, if we are called at all, that this board has
66f931551bSRalph Campbell 	 * QSFP. This is on the same i2c chain as the legacy parts,
67f931551bSRalph Campbell 	 * but only responds if the module is selected via GPIO pins.
68f931551bSRalph Campbell 	 * Further, there are very long setup and hold requirements
69f931551bSRalph Campbell 	 * on MODSEL.
70f931551bSRalph Campbell 	 */
71f931551bSRalph Campbell 	mask = QSFP_GPIO_MOD_SEL_N | QSFP_GPIO_MOD_RST_N | QSFP_GPIO_LP_MODE;
72f931551bSRalph Campbell 	out = QSFP_GPIO_MOD_RST_N | QSFP_GPIO_LP_MODE;
73f931551bSRalph Campbell 	if (ppd->hw_pidx) {
74f931551bSRalph Campbell 		mask <<= QSFP_GPIO_PORT2_SHIFT;
75f931551bSRalph Campbell 		out <<= QSFP_GPIO_PORT2_SHIFT;
76f931551bSRalph Campbell 	}
77f931551bSRalph Campbell 
78f931551bSRalph Campbell 	dd->f_gpio_mod(dd, out, mask, mask);
79f931551bSRalph Campbell 
80f931551bSRalph Campbell 	/*
81f931551bSRalph Campbell 	 * Module could take up to 2 Msec to respond to MOD_SEL, and there
82f931551bSRalph Campbell 	 * is no way to tell if it is ready, so we must wait.
83f931551bSRalph Campbell 	 */
84f931551bSRalph Campbell 	msleep(2);
85f931551bSRalph Campbell 
86f931551bSRalph Campbell 	/* Make sure TWSI bus is in sane state. */
87f931551bSRalph Campbell 	ret = qib_twsi_reset(dd);
88f931551bSRalph Campbell 	if (ret) {
89f931551bSRalph Campbell 		qib_dev_porterr(dd, ppd->port,
90f931551bSRalph Campbell 				"QSFP interface Reset for read failed\n");
91f931551bSRalph Campbell 		ret = -EIO;
92f931551bSRalph Campbell 		stuck = 1;
93f931551bSRalph Campbell 		goto deselect;
94f931551bSRalph Campbell 	}
95f931551bSRalph Campbell 
96f931551bSRalph Campbell 	/* All QSFP modules are at A0 */
97f931551bSRalph Campbell 
98f931551bSRalph Campbell 	cnt = 0;
99f931551bSRalph Campbell 	while (cnt < len) {
100f931551bSRalph Campbell 		unsigned in_page;
101f931551bSRalph Campbell 		int wlen = len - cnt;
102f931551bSRalph Campbell 		in_page = addr % QSFP_PAGESIZE;
103f931551bSRalph Campbell 		if ((in_page + wlen) > QSFP_PAGESIZE)
104f931551bSRalph Campbell 			wlen = QSFP_PAGESIZE - in_page;
105f931551bSRalph Campbell 		ret = qib_twsi_blk_rd(dd, QSFP_DEV, addr, buff + cnt, wlen);
106f931551bSRalph Campbell 		/* Some QSFP's fail first try. Retry as experiment */
107f931551bSRalph Campbell 		if (ret && cnt == 0 && ++pass < QSFP_MAX_RETRY)
108f931551bSRalph Campbell 			continue;
109f931551bSRalph Campbell 		if (ret) {
110f931551bSRalph Campbell 			/* qib_twsi_blk_rd() 1 for error, else 0 */
111f931551bSRalph Campbell 			ret = -EIO;
112f931551bSRalph Campbell 			goto deselect;
113f931551bSRalph Campbell 		}
114f931551bSRalph Campbell 		addr += wlen;
115f931551bSRalph Campbell 		cnt += wlen;
116f931551bSRalph Campbell 	}
117f931551bSRalph Campbell 	ret = cnt;
118f931551bSRalph Campbell 
119f931551bSRalph Campbell deselect:
120f931551bSRalph Campbell 	/*
121f931551bSRalph Campbell 	 * Module could take up to 10 uSec after transfer before
122f931551bSRalph Campbell 	 * ready to respond to MOD_SEL negation, and there is no way
123f931551bSRalph Campbell 	 * to tell if it is ready, so we must wait.
124f931551bSRalph Campbell 	 */
125f931551bSRalph Campbell 	udelay(10);
126f931551bSRalph Campbell 	/* set QSFP MODSEL, RST. LP all high */
127f931551bSRalph Campbell 	dd->f_gpio_mod(dd, mask, mask, mask);
128f931551bSRalph Campbell 
129f931551bSRalph Campbell 	/*
130f931551bSRalph Campbell 	 * Module could take up to 2 Msec to respond to MOD_SEL
131f931551bSRalph Campbell 	 * going away, and there is no way to tell if it is ready.
132f931551bSRalph Campbell 	 * so we must wait.
133f931551bSRalph Campbell 	 */
134f931551bSRalph Campbell 	if (stuck)
135f931551bSRalph Campbell 		qib_dev_err(dd, "QSFP interface bus stuck non-idle\n");
136f931551bSRalph Campbell 
137f931551bSRalph Campbell 	if (pass >= QSFP_MAX_RETRY && ret)
138f931551bSRalph Campbell 		qib_dev_porterr(dd, ppd->port, "QSFP failed even retrying\n");
139f931551bSRalph Campbell 	else if (pass)
140f931551bSRalph Campbell 		qib_dev_porterr(dd, ppd->port, "QSFP retries: %d\n", pass);
141f931551bSRalph Campbell 
142f931551bSRalph Campbell 	msleep(2);
143f931551bSRalph Campbell 
144f931551bSRalph Campbell bail:
145f931551bSRalph Campbell 	mutex_unlock(&dd->eep_lock);
146f931551bSRalph Campbell 
147f931551bSRalph Campbell no_unlock:
148f931551bSRalph Campbell 	return ret;
149f931551bSRalph Campbell }
150f931551bSRalph Campbell 
151f931551bSRalph Campbell /*
152f931551bSRalph Campbell  * qsfp_write
153f931551bSRalph Campbell  * We do not ordinarily write the QSFP, but this is needed to select
154f931551bSRalph Campbell  * the page on non-flat QSFPs, and possibly later unusual cases
155f931551bSRalph Campbell  */
156f931551bSRalph Campbell static int qib_qsfp_write(struct qib_pportdata *ppd, int addr, void *bp,
157f931551bSRalph Campbell 			  int len)
158f931551bSRalph Campbell {
159f931551bSRalph Campbell 	struct qib_devdata *dd = ppd->dd;
160f931551bSRalph Campbell 	u32 out, mask;
161f931551bSRalph Campbell 	int ret, cnt;
162f931551bSRalph Campbell 	u8 *buff = bp;
163f931551bSRalph Campbell 
164f931551bSRalph Campbell 	ret = mutex_lock_interruptible(&dd->eep_lock);
165f931551bSRalph Campbell 	if (ret)
166f931551bSRalph Campbell 		goto no_unlock;
167f931551bSRalph Campbell 
168f931551bSRalph Campbell 	if (dd->twsi_eeprom_dev == QIB_TWSI_NO_DEV) {
169f931551bSRalph Campbell 		ret = -ENXIO;
170f931551bSRalph Campbell 		goto bail;
171f931551bSRalph Campbell 	}
172f931551bSRalph Campbell 
173f931551bSRalph Campbell 	/*
174f931551bSRalph Campbell 	 * We presume, if we are called at all, that this board has
175f931551bSRalph Campbell 	 * QSFP. This is on the same i2c chain as the legacy parts,
176f931551bSRalph Campbell 	 * but only responds if the module is selected via GPIO pins.
177f931551bSRalph Campbell 	 * Further, there are very long setup and hold requirements
178f931551bSRalph Campbell 	 * on MODSEL.
179f931551bSRalph Campbell 	 */
180f931551bSRalph Campbell 	mask = QSFP_GPIO_MOD_SEL_N | QSFP_GPIO_MOD_RST_N | QSFP_GPIO_LP_MODE;
181f931551bSRalph Campbell 	out = QSFP_GPIO_MOD_RST_N | QSFP_GPIO_LP_MODE;
182f931551bSRalph Campbell 	if (ppd->hw_pidx) {
183f931551bSRalph Campbell 		mask <<= QSFP_GPIO_PORT2_SHIFT;
184f931551bSRalph Campbell 		out <<= QSFP_GPIO_PORT2_SHIFT;
185f931551bSRalph Campbell 	}
186f931551bSRalph Campbell 	dd->f_gpio_mod(dd, out, mask, mask);
187f931551bSRalph Campbell 
188f931551bSRalph Campbell 	/*
189f931551bSRalph Campbell 	 * Module could take up to 2 Msec to respond to MOD_SEL,
190f931551bSRalph Campbell 	 * and there is no way to tell if it is ready, so we must wait.
191f931551bSRalph Campbell 	 */
192f931551bSRalph Campbell 	msleep(2);
193f931551bSRalph Campbell 
194f931551bSRalph Campbell 	/* Make sure TWSI bus is in sane state. */
195f931551bSRalph Campbell 	ret = qib_twsi_reset(dd);
196f931551bSRalph Campbell 	if (ret) {
197f931551bSRalph Campbell 		qib_dev_porterr(dd, ppd->port,
198f931551bSRalph Campbell 				"QSFP interface Reset for write failed\n");
199f931551bSRalph Campbell 		ret = -EIO;
200f931551bSRalph Campbell 		goto deselect;
201f931551bSRalph Campbell 	}
202f931551bSRalph Campbell 
203f931551bSRalph Campbell 	/* All QSFP modules are at A0 */
204f931551bSRalph Campbell 
205f931551bSRalph Campbell 	cnt = 0;
206f931551bSRalph Campbell 	while (cnt < len) {
207f931551bSRalph Campbell 		unsigned in_page;
208f931551bSRalph Campbell 		int wlen = len - cnt;
209f931551bSRalph Campbell 		in_page = addr % QSFP_PAGESIZE;
210f931551bSRalph Campbell 		if ((in_page + wlen) > QSFP_PAGESIZE)
211f931551bSRalph Campbell 			wlen = QSFP_PAGESIZE - in_page;
212f931551bSRalph Campbell 		ret = qib_twsi_blk_wr(dd, QSFP_DEV, addr, buff + cnt, wlen);
213f931551bSRalph Campbell 		if (ret) {
214f931551bSRalph Campbell 			/* qib_twsi_blk_wr() 1 for error, else 0 */
215f931551bSRalph Campbell 			ret = -EIO;
216f931551bSRalph Campbell 			goto deselect;
217f931551bSRalph Campbell 		}
218f931551bSRalph Campbell 		addr += wlen;
219f931551bSRalph Campbell 		cnt += wlen;
220f931551bSRalph Campbell 	}
221f931551bSRalph Campbell 	ret = cnt;
222f931551bSRalph Campbell 
223f931551bSRalph Campbell deselect:
224f931551bSRalph Campbell 	/*
225f931551bSRalph Campbell 	 * Module could take up to 10 uSec after transfer before
226f931551bSRalph Campbell 	 * ready to respond to MOD_SEL negation, and there is no way
227f931551bSRalph Campbell 	 * to tell if it is ready, so we must wait.
228f931551bSRalph Campbell 	 */
229f931551bSRalph Campbell 	udelay(10);
230f931551bSRalph Campbell 	/* set QSFP MODSEL, RST, LP high */
231f931551bSRalph Campbell 	dd->f_gpio_mod(dd, mask, mask, mask);
232f931551bSRalph Campbell 	/*
233f931551bSRalph Campbell 	 * Module could take up to 2 Msec to respond to MOD_SEL
234f931551bSRalph Campbell 	 * going away, and there is no way to tell if it is ready.
235f931551bSRalph Campbell 	 * so we must wait.
236f931551bSRalph Campbell 	 */
237f931551bSRalph Campbell 	msleep(2);
238f931551bSRalph Campbell 
239f931551bSRalph Campbell bail:
240f931551bSRalph Campbell 	mutex_unlock(&dd->eep_lock);
241f931551bSRalph Campbell 
242f931551bSRalph Campbell no_unlock:
243f931551bSRalph Campbell 	return ret;
244f931551bSRalph Campbell }
245f931551bSRalph Campbell 
246f931551bSRalph Campbell /*
247f931551bSRalph Campbell  * For validation, we want to check the checksums, even of the
248f931551bSRalph Campbell  * fields we do not otherwise use. This function reads the bytes from
249f931551bSRalph Campbell  * <first> to <next-1> and returns the 8lsbs of the sum, or <0 for errors
250f931551bSRalph Campbell  */
251f931551bSRalph Campbell static int qsfp_cks(struct qib_pportdata *ppd, int first, int next)
252f931551bSRalph Campbell {
253f931551bSRalph Campbell 	int ret;
254f931551bSRalph Campbell 	u16 cks;
255f931551bSRalph Campbell 	u8 bval;
256f931551bSRalph Campbell 
257f931551bSRalph Campbell 	cks = 0;
258f931551bSRalph Campbell 	while (first < next) {
259f931551bSRalph Campbell 		ret = qsfp_read(ppd, first, &bval, 1);
260f931551bSRalph Campbell 		if (ret < 0)
261f931551bSRalph Campbell 			goto bail;
262f931551bSRalph Campbell 		cks += bval;
263f931551bSRalph Campbell 		++first;
264f931551bSRalph Campbell 	}
265f931551bSRalph Campbell 	ret = cks & 0xFF;
266f931551bSRalph Campbell bail:
267f931551bSRalph Campbell 	return ret;
268f931551bSRalph Campbell 
269f931551bSRalph Campbell }
270f931551bSRalph Campbell 
271f931551bSRalph Campbell int qib_refresh_qsfp_cache(struct qib_pportdata *ppd, struct qib_qsfp_cache *cp)
272f931551bSRalph Campbell {
273f931551bSRalph Campbell 	int ret;
274f931551bSRalph Campbell 	int idx;
275f931551bSRalph Campbell 	u16 cks;
276f931551bSRalph Campbell 	u8 peek[4];
277f931551bSRalph Campbell 
278f931551bSRalph Campbell 	/* ensure sane contents on invalid reads, for cable swaps */
279f931551bSRalph Campbell 	memset(cp, 0, sizeof(*cp));
280f931551bSRalph Campbell 
281*dde05cbdSMitko Haralanov 	if (!qib_qsfp_mod_present(ppd)) {
282f931551bSRalph Campbell 		ret = -ENODEV;
283f931551bSRalph Campbell 		goto bail;
284f931551bSRalph Campbell 	}
285f931551bSRalph Campbell 
286f931551bSRalph Campbell 	ret = qsfp_read(ppd, 0, peek, 3);
287f931551bSRalph Campbell 	if (ret < 0)
288f931551bSRalph Campbell 		goto bail;
289f931551bSRalph Campbell 	if ((peek[0] & 0xFE) != 0x0C)
290f931551bSRalph Campbell 		qib_dev_porterr(ppd->dd, ppd->port,
291f931551bSRalph Campbell 				"QSFP byte0 is 0x%02X, S/B 0x0C/D\n", peek[0]);
292f931551bSRalph Campbell 
293f931551bSRalph Campbell 	if ((peek[2] & 2) == 0) {
294f931551bSRalph Campbell 		/*
295f931551bSRalph Campbell 		 * If cable is paged, rather than "flat memory", we need to
296f931551bSRalph Campbell 		 * set the page to zero, Even if it already appears to be zero.
297f931551bSRalph Campbell 		 */
298f931551bSRalph Campbell 		u8 poke = 0;
299f931551bSRalph Campbell 		ret = qib_qsfp_write(ppd, 127, &poke, 1);
300f931551bSRalph Campbell 		udelay(50);
301f931551bSRalph Campbell 		if (ret != 1) {
302f931551bSRalph Campbell 			qib_dev_porterr(ppd->dd, ppd->port,
303f931551bSRalph Campbell 					"Failed QSFP Page set\n");
304f931551bSRalph Campbell 			goto bail;
305f931551bSRalph Campbell 		}
306f931551bSRalph Campbell 	}
307f931551bSRalph Campbell 
308f931551bSRalph Campbell 	ret = qsfp_read(ppd, QSFP_MOD_ID_OFFS, &cp->id, 1);
309f931551bSRalph Campbell 	if (ret < 0)
310f931551bSRalph Campbell 		goto bail;
311f931551bSRalph Campbell 	if ((cp->id & 0xFE) != 0x0C)
312f931551bSRalph Campbell 		qib_dev_porterr(ppd->dd, ppd->port,
313f931551bSRalph Campbell 				"QSFP ID byte is 0x%02X, S/B 0x0C/D\n", cp->id);
314f931551bSRalph Campbell 	cks = cp->id;
315f931551bSRalph Campbell 
316f931551bSRalph Campbell 	ret = qsfp_read(ppd, QSFP_MOD_PWR_OFFS, &cp->pwr, 1);
317f931551bSRalph Campbell 	if (ret < 0)
318f931551bSRalph Campbell 		goto bail;
319f931551bSRalph Campbell 	cks += cp->pwr;
320f931551bSRalph Campbell 
321f931551bSRalph Campbell 	ret = qsfp_cks(ppd, QSFP_MOD_PWR_OFFS + 1, QSFP_MOD_LEN_OFFS);
322f931551bSRalph Campbell 	if (ret < 0)
323f931551bSRalph Campbell 		goto bail;
324f931551bSRalph Campbell 	cks += ret;
325f931551bSRalph Campbell 
326f931551bSRalph Campbell 	ret = qsfp_read(ppd, QSFP_MOD_LEN_OFFS, &cp->len, 1);
327f931551bSRalph Campbell 	if (ret < 0)
328f931551bSRalph Campbell 		goto bail;
329f931551bSRalph Campbell 	cks += cp->len;
330f931551bSRalph Campbell 
331f931551bSRalph Campbell 	ret = qsfp_read(ppd, QSFP_MOD_TECH_OFFS, &cp->tech, 1);
332f931551bSRalph Campbell 	if (ret < 0)
333f931551bSRalph Campbell 		goto bail;
334f931551bSRalph Campbell 	cks += cp->tech;
335f931551bSRalph Campbell 
336f931551bSRalph Campbell 	ret = qsfp_read(ppd, QSFP_VEND_OFFS, &cp->vendor, QSFP_VEND_LEN);
337f931551bSRalph Campbell 	if (ret < 0)
338f931551bSRalph Campbell 		goto bail;
339f931551bSRalph Campbell 	for (idx = 0; idx < QSFP_VEND_LEN; ++idx)
340f931551bSRalph Campbell 		cks += cp->vendor[idx];
341f931551bSRalph Campbell 
342f931551bSRalph Campbell 	ret = qsfp_read(ppd, QSFP_IBXCV_OFFS, &cp->xt_xcv, 1);
343f931551bSRalph Campbell 	if (ret < 0)
344f931551bSRalph Campbell 		goto bail;
345f931551bSRalph Campbell 	cks += cp->xt_xcv;
346f931551bSRalph Campbell 
347f931551bSRalph Campbell 	ret = qsfp_read(ppd, QSFP_VOUI_OFFS, &cp->oui, QSFP_VOUI_LEN);
348f931551bSRalph Campbell 	if (ret < 0)
349f931551bSRalph Campbell 		goto bail;
350f931551bSRalph Campbell 	for (idx = 0; idx < QSFP_VOUI_LEN; ++idx)
351f931551bSRalph Campbell 		cks += cp->oui[idx];
352f931551bSRalph Campbell 
353f931551bSRalph Campbell 	ret = qsfp_read(ppd, QSFP_PN_OFFS, &cp->partnum, QSFP_PN_LEN);
354f931551bSRalph Campbell 	if (ret < 0)
355f931551bSRalph Campbell 		goto bail;
356f931551bSRalph Campbell 	for (idx = 0; idx < QSFP_PN_LEN; ++idx)
357f931551bSRalph Campbell 		cks += cp->partnum[idx];
358f931551bSRalph Campbell 
359f931551bSRalph Campbell 	ret = qsfp_read(ppd, QSFP_REV_OFFS, &cp->rev, QSFP_REV_LEN);
360f931551bSRalph Campbell 	if (ret < 0)
361f931551bSRalph Campbell 		goto bail;
362f931551bSRalph Campbell 	for (idx = 0; idx < QSFP_REV_LEN; ++idx)
363f931551bSRalph Campbell 		cks += cp->rev[idx];
364f931551bSRalph Campbell 
365f931551bSRalph Campbell 	ret = qsfp_read(ppd, QSFP_ATTEN_OFFS, &cp->atten, QSFP_ATTEN_LEN);
366f931551bSRalph Campbell 	if (ret < 0)
367f931551bSRalph Campbell 		goto bail;
368f931551bSRalph Campbell 	for (idx = 0; idx < QSFP_ATTEN_LEN; ++idx)
369f931551bSRalph Campbell 		cks += cp->atten[idx];
370f931551bSRalph Campbell 
371f931551bSRalph Campbell 	ret = qsfp_cks(ppd, QSFP_ATTEN_OFFS + QSFP_ATTEN_LEN, QSFP_CC_OFFS);
372f931551bSRalph Campbell 	if (ret < 0)
373f931551bSRalph Campbell 		goto bail;
374f931551bSRalph Campbell 	cks += ret;
375f931551bSRalph Campbell 
376f931551bSRalph Campbell 	cks &= 0xFF;
377f931551bSRalph Campbell 	ret = qsfp_read(ppd, QSFP_CC_OFFS, &cp->cks1, 1);
378f931551bSRalph Campbell 	if (ret < 0)
379f931551bSRalph Campbell 		goto bail;
380f931551bSRalph Campbell 	if (cks != cp->cks1)
381f931551bSRalph Campbell 		qib_dev_porterr(ppd->dd, ppd->port,
382f931551bSRalph Campbell 				"QSFP cks1 is %02X, computed %02X\n", cp->cks1,
383f931551bSRalph Campbell 				cks);
384f931551bSRalph Campbell 
385f931551bSRalph Campbell 	/* Second checksum covers 192 to (serial, date, lot) */
386f931551bSRalph Campbell 	ret = qsfp_cks(ppd, QSFP_CC_OFFS + 1, QSFP_SN_OFFS);
387f931551bSRalph Campbell 	if (ret < 0)
388f931551bSRalph Campbell 		goto bail;
389f931551bSRalph Campbell 	cks = ret;
390f931551bSRalph Campbell 
391f931551bSRalph Campbell 	ret = qsfp_read(ppd, QSFP_SN_OFFS, &cp->serial, QSFP_SN_LEN);
392f931551bSRalph Campbell 	if (ret < 0)
393f931551bSRalph Campbell 		goto bail;
394f931551bSRalph Campbell 	for (idx = 0; idx < QSFP_SN_LEN; ++idx)
395f931551bSRalph Campbell 		cks += cp->serial[idx];
396f931551bSRalph Campbell 
397f931551bSRalph Campbell 	ret = qsfp_read(ppd, QSFP_DATE_OFFS, &cp->date, QSFP_DATE_LEN);
398f931551bSRalph Campbell 	if (ret < 0)
399f931551bSRalph Campbell 		goto bail;
400f931551bSRalph Campbell 	for (idx = 0; idx < QSFP_DATE_LEN; ++idx)
401f931551bSRalph Campbell 		cks += cp->date[idx];
402f931551bSRalph Campbell 
403f931551bSRalph Campbell 	ret = qsfp_read(ppd, QSFP_LOT_OFFS, &cp->lot, QSFP_LOT_LEN);
404f931551bSRalph Campbell 	if (ret < 0)
405f931551bSRalph Campbell 		goto bail;
406f931551bSRalph Campbell 	for (idx = 0; idx < QSFP_LOT_LEN; ++idx)
407f931551bSRalph Campbell 		cks += cp->lot[idx];
408f931551bSRalph Campbell 
409f931551bSRalph Campbell 	ret = qsfp_cks(ppd, QSFP_LOT_OFFS + QSFP_LOT_LEN, QSFP_CC_EXT_OFFS);
410f931551bSRalph Campbell 	if (ret < 0)
411f931551bSRalph Campbell 		goto bail;
412f931551bSRalph Campbell 	cks += ret;
413f931551bSRalph Campbell 
414f931551bSRalph Campbell 	ret = qsfp_read(ppd, QSFP_CC_EXT_OFFS, &cp->cks2, 1);
415f931551bSRalph Campbell 	if (ret < 0)
416f931551bSRalph Campbell 		goto bail;
417f931551bSRalph Campbell 	cks &= 0xFF;
418f931551bSRalph Campbell 	if (cks != cp->cks2)
419f931551bSRalph Campbell 		qib_dev_porterr(ppd->dd, ppd->port,
420f931551bSRalph Campbell 				"QSFP cks2 is %02X, computed %02X\n", cp->cks2,
421f931551bSRalph Campbell 				cks);
422f931551bSRalph Campbell 	return 0;
423f931551bSRalph Campbell 
424f931551bSRalph Campbell bail:
425f931551bSRalph Campbell 	cp->id = 0;
426f931551bSRalph Campbell 	return ret;
427f931551bSRalph Campbell }
428f931551bSRalph Campbell 
429f931551bSRalph Campbell const char * const qib_qsfp_devtech[16] = {
430f931551bSRalph Campbell 	"850nm VCSEL", "1310nm VCSEL", "1550nm VCSEL", "1310nm FP",
431f931551bSRalph Campbell 	"1310nm DFB", "1550nm DFB", "1310nm EML", "1550nm EML",
432f931551bSRalph Campbell 	"Cu Misc", "1490nm DFB", "Cu NoEq", "Cu Eq",
433f931551bSRalph Campbell 	"Undef", "Cu Active BothEq", "Cu FarEq", "Cu NearEq"
434f931551bSRalph Campbell };
435f931551bSRalph Campbell 
436f931551bSRalph Campbell #define QSFP_DUMP_CHUNK 16 /* Holds longest string */
437f931551bSRalph Campbell #define QSFP_DEFAULT_HDR_CNT 224
438f931551bSRalph Campbell 
439f931551bSRalph Campbell static const char *pwr_codes = "1.5W2.0W2.5W3.5W";
440f931551bSRalph Campbell 
441*dde05cbdSMitko Haralanov int qib_qsfp_mod_present(struct qib_pportdata *ppd)
442*dde05cbdSMitko Haralanov {
443*dde05cbdSMitko Haralanov 	u32 mask;
444*dde05cbdSMitko Haralanov 	int ret;
445*dde05cbdSMitko Haralanov 
446*dde05cbdSMitko Haralanov 	mask = QSFP_GPIO_MOD_PRS_N <<
447*dde05cbdSMitko Haralanov 		(ppd->hw_pidx * QSFP_GPIO_PORT2_SHIFT);
448*dde05cbdSMitko Haralanov 	ret = ppd->dd->f_gpio_mod(ppd->dd, 0, 0, 0);
449*dde05cbdSMitko Haralanov 
450*dde05cbdSMitko Haralanov 	return !((ret & mask) >>
451*dde05cbdSMitko Haralanov 		 ((ppd->hw_pidx * QSFP_GPIO_PORT2_SHIFT) + 3));
452*dde05cbdSMitko Haralanov }
453*dde05cbdSMitko Haralanov 
454f931551bSRalph Campbell /*
455f931551bSRalph Campbell  * Initialize structures that control access to QSFP. Called once per port
456f931551bSRalph Campbell  * on cards that support QSFP.
457f931551bSRalph Campbell  */
458f931551bSRalph Campbell void qib_qsfp_init(struct qib_qsfp_data *qd,
459f931551bSRalph Campbell 		   void (*fevent)(struct work_struct *))
460f931551bSRalph Campbell {
461f931551bSRalph Campbell 	u32 mask, highs;
462f931551bSRalph Campbell 
463f931551bSRalph Campbell 	struct qib_devdata *dd = qd->ppd->dd;
464f931551bSRalph Campbell 
465f931551bSRalph Campbell 	/* Initialize work struct for later QSFP events */
466f931551bSRalph Campbell 	INIT_WORK(&qd->work, fevent);
467f931551bSRalph Campbell 
468f931551bSRalph Campbell 	/*
469f931551bSRalph Campbell 	 * Later, we may want more validation. For now, just set up pins and
470f931551bSRalph Campbell 	 * blip reset. If module is present, call qib_refresh_qsfp_cache(),
471f931551bSRalph Campbell 	 * to do further init.
472f931551bSRalph Campbell 	 */
473f931551bSRalph Campbell 	mask = QSFP_GPIO_MOD_SEL_N | QSFP_GPIO_MOD_RST_N | QSFP_GPIO_LP_MODE;
474f931551bSRalph Campbell 	highs = mask - QSFP_GPIO_MOD_RST_N;
475f931551bSRalph Campbell 	if (qd->ppd->hw_pidx) {
476f931551bSRalph Campbell 		mask <<= QSFP_GPIO_PORT2_SHIFT;
477f931551bSRalph Campbell 		highs <<= QSFP_GPIO_PORT2_SHIFT;
478f931551bSRalph Campbell 	}
479f931551bSRalph Campbell 	dd->f_gpio_mod(dd, highs, mask, mask);
480f931551bSRalph Campbell 	udelay(20); /* Generous RST dwell */
481f931551bSRalph Campbell 
482f931551bSRalph Campbell 	dd->f_gpio_mod(dd, mask, mask, mask);
483f931551bSRalph Campbell 	/* Spec says module can take up to two seconds! */
484f931551bSRalph Campbell 	mask = QSFP_GPIO_MOD_PRS_N;
485f931551bSRalph Campbell 	if (qd->ppd->hw_pidx)
486f931551bSRalph Campbell 		mask <<= QSFP_GPIO_PORT2_SHIFT;
487f931551bSRalph Campbell 
488f931551bSRalph Campbell 	/* Do not try to wait here. Better to let event handle it */
489*dde05cbdSMitko Haralanov 	if (!qib_qsfp_mod_present(qd->ppd))
490f931551bSRalph Campbell 		goto bail;
491f931551bSRalph Campbell 	/* We see a module, but it may be unwise to look yet. Just schedule */
492f931551bSRalph Campbell 	qd->t_insert = get_jiffies_64();
493f0626710STejun Heo 	queue_work(ib_wq, &qd->work);
494f931551bSRalph Campbell bail:
495f931551bSRalph Campbell 	return;
496f931551bSRalph Campbell }
497f931551bSRalph Campbell 
498f931551bSRalph Campbell void qib_qsfp_deinit(struct qib_qsfp_data *qd)
499f931551bSRalph Campbell {
500f931551bSRalph Campbell 	/*
501f0626710STejun Heo 	 * There is nothing to do here for now.  our work is scheduled
502f0626710STejun Heo 	 * with queue_work(), and flush_workqueue() from remove_one
503f0626710STejun Heo 	 * will block until all work setup with queue_work()
504f931551bSRalph Campbell 	 * completes.
505f931551bSRalph Campbell 	 */
506f931551bSRalph Campbell }
507f931551bSRalph Campbell 
508f931551bSRalph Campbell int qib_qsfp_dump(struct qib_pportdata *ppd, char *buf, int len)
509f931551bSRalph Campbell {
510f931551bSRalph Campbell 	struct qib_qsfp_cache cd;
511f931551bSRalph Campbell 	u8 bin_buff[QSFP_DUMP_CHUNK];
512f931551bSRalph Campbell 	char lenstr[6];
513f931551bSRalph Campbell 	int sofar, ret;
514f931551bSRalph Campbell 	int bidx = 0;
515f931551bSRalph Campbell 
516f931551bSRalph Campbell 	sofar = 0;
517f931551bSRalph Campbell 	ret = qib_refresh_qsfp_cache(ppd, &cd);
518f931551bSRalph Campbell 	if (ret < 0)
519f931551bSRalph Campbell 		goto bail;
520f931551bSRalph Campbell 
521f931551bSRalph Campbell 	lenstr[0] = ' ';
522f931551bSRalph Campbell 	lenstr[1] = '\0';
523f931551bSRalph Campbell 	if (QSFP_IS_CU(cd.tech))
524f931551bSRalph Campbell 		sprintf(lenstr, "%dM ", cd.len);
525f931551bSRalph Campbell 
526f931551bSRalph Campbell 	sofar += scnprintf(buf + sofar, len - sofar, "PWR:%.3sW\n", pwr_codes +
527f931551bSRalph Campbell 			   (QSFP_PWR(cd.pwr) * 4));
528f931551bSRalph Campbell 
529f931551bSRalph Campbell 	sofar += scnprintf(buf + sofar, len - sofar, "TECH:%s%s\n", lenstr,
530f931551bSRalph Campbell 			   qib_qsfp_devtech[cd.tech >> 4]);
531f931551bSRalph Campbell 
532f931551bSRalph Campbell 	sofar += scnprintf(buf + sofar, len - sofar, "Vendor:%.*s\n",
533f931551bSRalph Campbell 			   QSFP_VEND_LEN, cd.vendor);
534f931551bSRalph Campbell 
535f931551bSRalph Campbell 	sofar += scnprintf(buf + sofar, len - sofar, "OUI:%06X\n",
536f931551bSRalph Campbell 			   QSFP_OUI(cd.oui));
537f931551bSRalph Campbell 
538f931551bSRalph Campbell 	sofar += scnprintf(buf + sofar, len - sofar, "Part#:%.*s\n",
539f931551bSRalph Campbell 			   QSFP_PN_LEN, cd.partnum);
540f931551bSRalph Campbell 	sofar += scnprintf(buf + sofar, len - sofar, "Rev:%.*s\n",
541f931551bSRalph Campbell 			   QSFP_REV_LEN, cd.rev);
542f931551bSRalph Campbell 	if (QSFP_IS_CU(cd.tech))
543f931551bSRalph Campbell 		sofar += scnprintf(buf + sofar, len - sofar, "Atten:%d, %d\n",
544f931551bSRalph Campbell 				   QSFP_ATTEN_SDR(cd.atten),
545f931551bSRalph Campbell 				   QSFP_ATTEN_DDR(cd.atten));
546f931551bSRalph Campbell 	sofar += scnprintf(buf + sofar, len - sofar, "Serial:%.*s\n",
547f931551bSRalph Campbell 			   QSFP_SN_LEN, cd.serial);
548f931551bSRalph Campbell 	sofar += scnprintf(buf + sofar, len - sofar, "Date:%.*s\n",
549f931551bSRalph Campbell 			   QSFP_DATE_LEN, cd.date);
550f931551bSRalph Campbell 	sofar += scnprintf(buf + sofar, len - sofar, "Lot:%.*s\n",
551f931551bSRalph Campbell 			   QSFP_LOT_LEN, cd.date);
552f931551bSRalph Campbell 
553f931551bSRalph Campbell 	while (bidx < QSFP_DEFAULT_HDR_CNT) {
554f931551bSRalph Campbell 		int iidx;
555f931551bSRalph Campbell 		ret = qsfp_read(ppd, bidx, bin_buff, QSFP_DUMP_CHUNK);
556f931551bSRalph Campbell 		if (ret < 0)
557f931551bSRalph Campbell 			goto bail;
558f931551bSRalph Campbell 		for (iidx = 0; iidx < ret; ++iidx) {
559f931551bSRalph Campbell 			sofar += scnprintf(buf + sofar, len-sofar, " %02X",
560f931551bSRalph Campbell 				bin_buff[iidx]);
561f931551bSRalph Campbell 		}
562f931551bSRalph Campbell 		sofar += scnprintf(buf + sofar, len - sofar, "\n");
563f931551bSRalph Campbell 		bidx += QSFP_DUMP_CHUNK;
564f931551bSRalph Campbell 	}
565f931551bSRalph Campbell 	ret = sofar;
566f931551bSRalph Campbell bail:
567f931551bSRalph Campbell 	return ret;
568f931551bSRalph Campbell }
569