Example #1
0
File: qib_qsfp.c Project: 01org/qib
int qib_refresh_qsfp_cache(struct qib_pportdata *ppd, struct qib_qsfp_cache *cp)
{
	int ret;
	int idx;
	u16 cks;
	u8 peek[4];

	/* ensure sane contents on invalid reads, for cable swaps */
	memset(cp, 0, sizeof(*cp));

	if (!qib_qsfp_mod_present(ppd)) {
		qib_dbg("No QSFP module in %d:%d\n", ppd->dd->unit, ppd->port);
		ret = -ENODEV;
		goto bail;
	}

	ret = qsfp_read(ppd, 0, peek, 3);
	if (ret < 0)
		goto bail;
	if ((peek[0] & 0xFE) != 0x0C)
		qib_dev_porterr(ppd->dd, ppd->port,
				"QSFP byte0 is 0x%02X, S/B 0x0C/D\n", peek[0]);

	if ((peek[2] & 2) == 0) {
		/*
		 * If cable is paged, rather than "flat memory", we need to
		 * set the page to zero, Even if it already appears to be zero.
		 */
		u8 poke = 0;
		ret = qib_qsfp_write(ppd, 127, &poke, 1);
		udelay(50);
		if (ret != 1) {
			qib_dev_porterr(ppd->dd, ppd->port,
					"Failed QSFP Page set\n");
			goto bail;
		}
	}

	ret = qsfp_read(ppd, QSFP_MOD_ID_OFFS, &cp->id, 1);
	if (ret < 0)
		goto bail;
	if ((cp->id & 0xFE) != 0x0C)
		qib_dev_porterr(ppd->dd, ppd->port,
				"QSFP ID byte is 0x%02X, S/B 0x0C/D\n", cp->id);
	cks = cp->id;

	ret = qsfp_read(ppd, QSFP_MOD_PWR_OFFS, &cp->pwr, 1);
	if (ret < 0)
		goto bail;
	cks += cp->pwr;

	ret = qsfp_cks(ppd, QSFP_MOD_PWR_OFFS + 1, QSFP_MOD_LEN_OFFS);
	if (ret < 0)
		goto bail;
	cks += ret;

	ret = qsfp_read(ppd, QSFP_MOD_LEN_OFFS, &cp->len, 1);
	if (ret < 0)
		goto bail;
	cks += cp->len;

	ret = qsfp_read(ppd, QSFP_MOD_TECH_OFFS, &cp->tech, 1);
	if (ret < 0)
		goto bail;
	cks += cp->tech;

	ret = qsfp_read(ppd, QSFP_VEND_OFFS, &cp->vendor, QSFP_VEND_LEN);
	if (ret < 0)
		goto bail;
	for (idx = 0; idx < QSFP_VEND_LEN; ++idx)
		cks += cp->vendor[idx];

	ret = qsfp_read(ppd, QSFP_IBXCV_OFFS, &cp->xt_xcv, 1);
	if (ret < 0)
		goto bail;
	cks += cp->xt_xcv;

	ret = qsfp_read(ppd, QSFP_VOUI_OFFS, &cp->oui, QSFP_VOUI_LEN);
	if (ret < 0)
		goto bail;
	for (idx = 0; idx < QSFP_VOUI_LEN; ++idx)
		cks += cp->oui[idx];

	ret = qsfp_read(ppd, QSFP_PN_OFFS, &cp->partnum, QSFP_PN_LEN);
	if (ret < 0)
		goto bail;
	for (idx = 0; idx < QSFP_PN_LEN; ++idx)
		cks += cp->partnum[idx];

	ret = qsfp_read(ppd, QSFP_REV_OFFS, &cp->rev, QSFP_REV_LEN);
	if (ret < 0)
		goto bail;
	for (idx = 0; idx < QSFP_REV_LEN; ++idx)
		cks += cp->rev[idx];

	ret = qsfp_read(ppd, QSFP_ATTEN_OFFS, &cp->atten, QSFP_ATTEN_LEN);
	if (ret < 0)
		goto bail;
	for (idx = 0; idx < QSFP_ATTEN_LEN; ++idx)
		cks += cp->atten[idx];

	ret = qsfp_cks(ppd, QSFP_ATTEN_OFFS + QSFP_ATTEN_LEN, QSFP_CC_OFFS);
	if (ret < 0)
		goto bail;
	cks += ret;

	cks &= 0xFF;
	ret = qsfp_read(ppd, QSFP_CC_OFFS, &cp->cks1, 1);
	if (ret < 0)
		goto bail;
	if (cks != cp->cks1)
		qib_dev_porterr(ppd->dd, ppd->port,
				"QSFP cks1 is %02X, computed %02X\n", cp->cks1,
				cks);

	/* Second checksum covers 192 to (serial, date, lot) */
	ret = qsfp_cks(ppd, QSFP_CC_OFFS + 1, QSFP_SN_OFFS);
	if (ret < 0)
		goto bail;
	cks = ret;

	ret = qsfp_read(ppd, QSFP_SN_OFFS, &cp->serial, QSFP_SN_LEN);
	if (ret < 0)
		goto bail;
	for (idx = 0; idx < QSFP_SN_LEN; ++idx)
		cks += cp->serial[idx];

	ret = qsfp_read(ppd, QSFP_DATE_OFFS, &cp->date, QSFP_DATE_LEN);
	if (ret < 0)
		goto bail;
	for (idx = 0; idx < QSFP_DATE_LEN; ++idx)
		cks += cp->date[idx];

	ret = qsfp_read(ppd, QSFP_LOT_OFFS, &cp->lot, QSFP_LOT_LEN);
	if (ret < 0)
		goto bail;
	for (idx = 0; idx < QSFP_LOT_LEN; ++idx)
		cks += cp->lot[idx];

	ret = qsfp_cks(ppd, QSFP_LOT_OFFS + QSFP_LOT_LEN, QSFP_CC_EXT_OFFS);
	if (ret < 0)
		goto bail;
	cks += ret;

	ret = qsfp_read(ppd, QSFP_CC_EXT_OFFS, &cp->cks2, 1);
	if (ret < 0)
		goto bail;
	cks &= 0xFF;
	if (cks != cp->cks2)
		qib_dev_porterr(ppd->dd, ppd->port,
				"QSFP cks2 is %02X, computed %02X\n", cp->cks2,
				cks);
	return 0;

bail:
	cp->id = 0;
	return ret;
}
Example #2
0
File: qib_qsfp.c Project: 01org/qib
static int qsfp_read(struct qib_pportdata *ppd, int addr, void *bp, int len)
{
	struct qib_devdata *dd = ppd->dd;
	u32 out, mask;
	int ret, cnt, pass = 0;
	int stuck = 0;
	u8 *buff = bp;

	qib_cdbg(VERBOSE, "Grabbing Mutex for QSFP in %d:%d\n", dd->unit,
		 ppd->port);
	ret = mutex_lock_interruptible(&dd->eep_lock);
	if (ret)
		goto no_unlock;

	if (dd->twsi_eeprom_dev == QIB_TWSI_NO_DEV) {
		qib_dbg("QSFP read on board without QSFP\n");
		ret = -ENXIO;
		goto bail;
	}

	/*
	 * We presume, if we are called at all, that this board has
	 * QSFP. This is on the same i2c chain as the legacy parts,
	 * but only responds if the module is selected via GPIO pins.
	 * Further, there are very long setup and hold requirements
	 * on MODSEL.
	 */
	mask = QSFP_GPIO_MOD_SEL_N | QSFP_GPIO_MOD_RST_N | QSFP_GPIO_LP_MODE;
	out = QSFP_GPIO_MOD_RST_N | QSFP_GPIO_LP_MODE;
	if (ppd->hw_pidx) {
		mask <<= QSFP_GPIO_PORT2_SHIFT;
		out <<= QSFP_GPIO_PORT2_SHIFT;
	}

	dd->f_gpio_mod(dd, out, mask, mask);

	/*
	 * Module could take up to 2 Msec to respond to MOD_SEL, and there
	 * is no way to tell if it is ready, so we must wait.
	 */
	msleep(2);

	/* Make sure TWSI bus is in sane state. */
	ret = qib_twsi_reset(dd);
	if (ret) {
		qib_dev_porterr(dd, ppd->port,
				"QSFP interface Reset for read failed\n");
		ret = -EIO;
		stuck = 1;
		goto deselect;
	}

	/* All QSFP modules are at A0 */

	cnt = 0;
	while (cnt < len) {
		unsigned in_page;
		int wlen = len - cnt;
		in_page = addr % QSFP_PAGESIZE;
		if ((in_page + wlen) > QSFP_PAGESIZE)
			wlen = QSFP_PAGESIZE - in_page;
		ret = qib_twsi_blk_rd(dd, QSFP_DEV, addr, buff + cnt, wlen);
		/* Some QSFP's fail first try. Retry as experiment */
		if (ret && cnt == 0 && ++pass < QSFP_MAX_RETRY)
			continue;
		if (ret) {
			/* qib_twsi_blk_rd() 1 for error, else 0 */
			ret = -EIO;
			goto deselect;
		}
		addr += wlen;
		cnt += wlen;
	}
	ret = cnt;

deselect:
	/*
	 * Module could take up to 10 uSec after transfer before
	 * ready to respond to MOD_SEL negation, and there is no way
	 * to tell if it is ready, so we must wait.
	 */
	udelay(10);
	/* set QSFP MODSEL, RST. LP all high */
	dd->f_gpio_mod(dd, mask, mask, mask);

	/*
	 * Module could take up to 2 Msec to respond to MOD_SEL
	 * going away, and there is no way to tell if it is ready.
	 * so we must wait.
	 */
	if (stuck)
		qib_dev_err(dd, "QSFP interface bus stuck non-idle\n");

	if (pass >= QSFP_MAX_RETRY && ret)
		qib_dev_porterr(dd, ppd->port, "QSFP failed even retrying\n");
	else if (pass)
		qib_dev_porterr(dd, ppd->port, "QSFP retries: %d\n", pass);

	msleep(2);

bail:
	mutex_unlock(&dd->eep_lock);
	qib_cdbg(VERBOSE, "Released Mutex for QSFP %d:%d, ret %d\n", dd->unit,
		ppd->port, ret);

no_unlock:
	return ret;
}
/*
 * qsfp_write
 * We do not ordinarily write the QSFP, but this is needed to select
 * the page on non-flat QSFPs, and possibly later unusual cases
 */
static int qib_qsfp_write(struct qib_pportdata *ppd, int addr, void *bp,
			  int len)
{
	struct qib_devdata *dd = ppd->dd;
	u32 out, mask;
	int ret, cnt;
	u8 *buff = bp;

	ret = mutex_lock_interruptible(&dd->eep_lock);
	if (ret)
		goto no_unlock;

	if (dd->twsi_eeprom_dev == QIB_TWSI_NO_DEV) {
		ret = -ENXIO;
		goto bail;
	}

	/*
	 * We presume, if we are called at all, that this board has
	 * QSFP. This is on the same i2c chain as the legacy parts,
	 * but only responds if the module is selected via GPIO pins.
	 * Further, there are very long setup and hold requirements
	 * on MODSEL.
	 */
	mask = QSFP_GPIO_MOD_SEL_N | QSFP_GPIO_MOD_RST_N | QSFP_GPIO_LP_MODE;
	out = QSFP_GPIO_MOD_RST_N | QSFP_GPIO_LP_MODE;
	if (ppd->hw_pidx) {
		mask <<= QSFP_GPIO_PORT2_SHIFT;
		out <<= QSFP_GPIO_PORT2_SHIFT;
	}
	dd->f_gpio_mod(dd, out, mask, mask);

	/*
	 * Module could take up to 2 Msec to respond to MOD_SEL,
	 * and there is no way to tell if it is ready, so we must wait.
	 */
	msleep(2);

	/* Make sure TWSI bus is in sane state. */
	ret = qib_twsi_reset(dd);
	if (ret) {
		qib_dev_porterr(dd, ppd->port,
				"QSFP interface Reset for write failed\n");
		ret = -EIO;
		goto deselect;
	}

	/* All QSFP modules are at A0 */

	cnt = 0;
	while (cnt < len) {
		unsigned in_page;
		int wlen = len - cnt;
		in_page = addr % QSFP_PAGESIZE;
		if ((in_page + wlen) > QSFP_PAGESIZE)
			wlen = QSFP_PAGESIZE - in_page;
		ret = qib_twsi_blk_wr(dd, QSFP_DEV, addr, buff + cnt, wlen);
		if (ret) {
			/* qib_twsi_blk_wr() 1 for error, else 0 */
			ret = -EIO;
			goto deselect;
		}
		addr += wlen;
		cnt += wlen;
	}
	ret = cnt;

deselect:
	/*
	 * Module could take up to 10 uSec after transfer before
	 * ready to respond to MOD_SEL negation, and there is no way
	 * to tell if it is ready, so we must wait.
	 */
	udelay(10);
	/* set QSFP MODSEL, RST, LP high */
	dd->f_gpio_mod(dd, mask, mask, mask);
	/*
	 * Module could take up to 2 Msec to respond to MOD_SEL
	 * going away, and there is no way to tell if it is ready.
	 * so we must wait.
	 */
	msleep(2);

bail:
	mutex_unlock(&dd->eep_lock);

no_unlock:
	return ret;
}