0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 #include <linux/delay.h>
0035 #include <linux/pci.h>
0036 #include <linux/vmalloc.h>
0037
0038 #include "qib.h"
0039 #include "qib_qsfp.h"
0040
0041
0042
0043
0044
0045 #define QSFP_MAX_RETRY 4
0046
0047 static int qsfp_read(struct qib_pportdata *ppd, int addr, void *bp, int len)
0048 {
0049 struct qib_devdata *dd = ppd->dd;
0050 u32 out, mask;
0051 int ret, cnt, pass = 0;
0052 int stuck = 0;
0053 u8 *buff = bp;
0054
0055 ret = mutex_lock_interruptible(&dd->eep_lock);
0056 if (ret)
0057 goto no_unlock;
0058
0059 if (dd->twsi_eeprom_dev == QIB_TWSI_NO_DEV) {
0060 ret = -ENXIO;
0061 goto bail;
0062 }
0063
0064
0065
0066
0067
0068
0069
0070
0071 mask = QSFP_GPIO_MOD_SEL_N | QSFP_GPIO_MOD_RST_N | QSFP_GPIO_LP_MODE;
0072 out = QSFP_GPIO_MOD_RST_N | QSFP_GPIO_LP_MODE;
0073 if (ppd->hw_pidx) {
0074 mask <<= QSFP_GPIO_PORT2_SHIFT;
0075 out <<= QSFP_GPIO_PORT2_SHIFT;
0076 }
0077
0078 dd->f_gpio_mod(dd, out, mask, mask);
0079
0080
0081
0082
0083
0084 msleep(20);
0085
0086
0087 ret = qib_twsi_reset(dd);
0088 if (ret) {
0089 qib_dev_porterr(dd, ppd->port,
0090 "QSFP interface Reset for read failed\n");
0091 ret = -EIO;
0092 stuck = 1;
0093 goto deselect;
0094 }
0095
0096
0097
0098 cnt = 0;
0099 while (cnt < len) {
0100 unsigned in_page;
0101 int wlen = len - cnt;
0102
0103 in_page = addr % QSFP_PAGESIZE;
0104 if ((in_page + wlen) > QSFP_PAGESIZE)
0105 wlen = QSFP_PAGESIZE - in_page;
0106 ret = qib_twsi_blk_rd(dd, QSFP_DEV, addr, buff + cnt, wlen);
0107
0108 if (ret && cnt == 0 && ++pass < QSFP_MAX_RETRY)
0109 continue;
0110 if (ret) {
0111
0112 ret = -EIO;
0113 goto deselect;
0114 }
0115 addr += wlen;
0116 cnt += wlen;
0117 }
0118 ret = cnt;
0119
0120 deselect:
0121
0122
0123
0124
0125
0126 udelay(10);
0127
0128 dd->f_gpio_mod(dd, mask, mask, mask);
0129
0130
0131
0132
0133
0134
0135 if (stuck)
0136 qib_dev_err(dd, "QSFP interface bus stuck non-idle\n");
0137
0138 if (pass >= QSFP_MAX_RETRY && ret)
0139 qib_dev_porterr(dd, ppd->port, "QSFP failed even retrying\n");
0140 else if (pass)
0141 qib_dev_porterr(dd, ppd->port, "QSFP retries: %d\n", pass);
0142
0143 msleep(20);
0144
0145 bail:
0146 mutex_unlock(&dd->eep_lock);
0147
0148 no_unlock:
0149 return ret;
0150 }
0151
0152
0153
0154
0155
0156
0157 static int qib_qsfp_write(struct qib_pportdata *ppd, int addr, void *bp,
0158 int len)
0159 {
0160 struct qib_devdata *dd = ppd->dd;
0161 u32 out, mask;
0162 int ret, cnt;
0163 u8 *buff = bp;
0164
0165 ret = mutex_lock_interruptible(&dd->eep_lock);
0166 if (ret)
0167 goto no_unlock;
0168
0169 if (dd->twsi_eeprom_dev == QIB_TWSI_NO_DEV) {
0170 ret = -ENXIO;
0171 goto bail;
0172 }
0173
0174
0175
0176
0177
0178
0179
0180
0181 mask = QSFP_GPIO_MOD_SEL_N | QSFP_GPIO_MOD_RST_N | QSFP_GPIO_LP_MODE;
0182 out = QSFP_GPIO_MOD_RST_N | QSFP_GPIO_LP_MODE;
0183 if (ppd->hw_pidx) {
0184 mask <<= QSFP_GPIO_PORT2_SHIFT;
0185 out <<= QSFP_GPIO_PORT2_SHIFT;
0186 }
0187 dd->f_gpio_mod(dd, out, mask, mask);
0188
0189
0190
0191
0192
0193 msleep(20);
0194
0195
0196 ret = qib_twsi_reset(dd);
0197 if (ret) {
0198 qib_dev_porterr(dd, ppd->port,
0199 "QSFP interface Reset for write failed\n");
0200 ret = -EIO;
0201 goto deselect;
0202 }
0203
0204
0205
0206 cnt = 0;
0207 while (cnt < len) {
0208 unsigned in_page;
0209 int wlen = len - cnt;
0210
0211 in_page = addr % QSFP_PAGESIZE;
0212 if ((in_page + wlen) > QSFP_PAGESIZE)
0213 wlen = QSFP_PAGESIZE - in_page;
0214 ret = qib_twsi_blk_wr(dd, QSFP_DEV, addr, buff + cnt, wlen);
0215 if (ret) {
0216
0217 ret = -EIO;
0218 goto deselect;
0219 }
0220 addr += wlen;
0221 cnt += wlen;
0222 }
0223 ret = cnt;
0224
0225 deselect:
0226
0227
0228
0229
0230
0231 udelay(10);
0232
0233 dd->f_gpio_mod(dd, mask, mask, mask);
0234
0235
0236
0237
0238
0239 msleep(20);
0240
0241 bail:
0242 mutex_unlock(&dd->eep_lock);
0243
0244 no_unlock:
0245 return ret;
0246 }
0247
0248
0249
0250
0251
0252
0253 static int qsfp_cks(struct qib_pportdata *ppd, int first, int next)
0254 {
0255 int ret;
0256 u16 cks;
0257 u8 bval;
0258
0259 cks = 0;
0260 while (first < next) {
0261 ret = qsfp_read(ppd, first, &bval, 1);
0262 if (ret < 0)
0263 goto bail;
0264 cks += bval;
0265 ++first;
0266 }
0267 ret = cks & 0xFF;
0268 bail:
0269 return ret;
0270
0271 }
0272
0273 int qib_refresh_qsfp_cache(struct qib_pportdata *ppd, struct qib_qsfp_cache *cp)
0274 {
0275 int ret;
0276 int idx;
0277 u16 cks;
0278 u8 peek[4];
0279
0280
0281 memset(cp, 0, sizeof(*cp));
0282
0283 if (!qib_qsfp_mod_present(ppd)) {
0284 ret = -ENODEV;
0285 goto bail;
0286 }
0287
0288 ret = qsfp_read(ppd, 0, peek, 3);
0289 if (ret < 0)
0290 goto bail;
0291 if ((peek[0] & 0xFE) != 0x0C)
0292 qib_dev_porterr(ppd->dd, ppd->port,
0293 "QSFP byte0 is 0x%02X, S/B 0x0C/D\n", peek[0]);
0294
0295 if ((peek[2] & 4) == 0) {
0296
0297
0298
0299
0300 u8 poke = 0;
0301
0302 ret = qib_qsfp_write(ppd, 127, &poke, 1);
0303 udelay(50);
0304 if (ret != 1) {
0305 qib_dev_porterr(ppd->dd, ppd->port,
0306 "Failed QSFP Page set\n");
0307 goto bail;
0308 }
0309 }
0310
0311 ret = qsfp_read(ppd, QSFP_MOD_ID_OFFS, &cp->id, 1);
0312 if (ret < 0)
0313 goto bail;
0314 if ((cp->id & 0xFE) != 0x0C)
0315 qib_dev_porterr(ppd->dd, ppd->port,
0316 "QSFP ID byte is 0x%02X, S/B 0x0C/D\n", cp->id);
0317 cks = cp->id;
0318
0319 ret = qsfp_read(ppd, QSFP_MOD_PWR_OFFS, &cp->pwr, 1);
0320 if (ret < 0)
0321 goto bail;
0322 cks += cp->pwr;
0323
0324 ret = qsfp_cks(ppd, QSFP_MOD_PWR_OFFS + 1, QSFP_MOD_LEN_OFFS);
0325 if (ret < 0)
0326 goto bail;
0327 cks += ret;
0328
0329 ret = qsfp_read(ppd, QSFP_MOD_LEN_OFFS, &cp->len, 1);
0330 if (ret < 0)
0331 goto bail;
0332 cks += cp->len;
0333
0334 ret = qsfp_read(ppd, QSFP_MOD_TECH_OFFS, &cp->tech, 1);
0335 if (ret < 0)
0336 goto bail;
0337 cks += cp->tech;
0338
0339 ret = qsfp_read(ppd, QSFP_VEND_OFFS, &cp->vendor, QSFP_VEND_LEN);
0340 if (ret < 0)
0341 goto bail;
0342 for (idx = 0; idx < QSFP_VEND_LEN; ++idx)
0343 cks += cp->vendor[idx];
0344
0345 ret = qsfp_read(ppd, QSFP_IBXCV_OFFS, &cp->xt_xcv, 1);
0346 if (ret < 0)
0347 goto bail;
0348 cks += cp->xt_xcv;
0349
0350 ret = qsfp_read(ppd, QSFP_VOUI_OFFS, &cp->oui, QSFP_VOUI_LEN);
0351 if (ret < 0)
0352 goto bail;
0353 for (idx = 0; idx < QSFP_VOUI_LEN; ++idx)
0354 cks += cp->oui[idx];
0355
0356 ret = qsfp_read(ppd, QSFP_PN_OFFS, &cp->partnum, QSFP_PN_LEN);
0357 if (ret < 0)
0358 goto bail;
0359 for (idx = 0; idx < QSFP_PN_LEN; ++idx)
0360 cks += cp->partnum[idx];
0361
0362 ret = qsfp_read(ppd, QSFP_REV_OFFS, &cp->rev, QSFP_REV_LEN);
0363 if (ret < 0)
0364 goto bail;
0365 for (idx = 0; idx < QSFP_REV_LEN; ++idx)
0366 cks += cp->rev[idx];
0367
0368 ret = qsfp_read(ppd, QSFP_ATTEN_OFFS, &cp->atten, QSFP_ATTEN_LEN);
0369 if (ret < 0)
0370 goto bail;
0371 for (idx = 0; idx < QSFP_ATTEN_LEN; ++idx)
0372 cks += cp->atten[idx];
0373
0374 ret = qsfp_cks(ppd, QSFP_ATTEN_OFFS + QSFP_ATTEN_LEN, QSFP_CC_OFFS);
0375 if (ret < 0)
0376 goto bail;
0377 cks += ret;
0378
0379 cks &= 0xFF;
0380 ret = qsfp_read(ppd, QSFP_CC_OFFS, &cp->cks1, 1);
0381 if (ret < 0)
0382 goto bail;
0383 if (cks != cp->cks1)
0384 qib_dev_porterr(ppd->dd, ppd->port,
0385 "QSFP cks1 is %02X, computed %02X\n", cp->cks1,
0386 cks);
0387
0388
0389 ret = qsfp_cks(ppd, QSFP_CC_OFFS + 1, QSFP_SN_OFFS);
0390 if (ret < 0)
0391 goto bail;
0392 cks = ret;
0393
0394 ret = qsfp_read(ppd, QSFP_SN_OFFS, &cp->serial, QSFP_SN_LEN);
0395 if (ret < 0)
0396 goto bail;
0397 for (idx = 0; idx < QSFP_SN_LEN; ++idx)
0398 cks += cp->serial[idx];
0399
0400 ret = qsfp_read(ppd, QSFP_DATE_OFFS, &cp->date, QSFP_DATE_LEN);
0401 if (ret < 0)
0402 goto bail;
0403 for (idx = 0; idx < QSFP_DATE_LEN; ++idx)
0404 cks += cp->date[idx];
0405
0406 ret = qsfp_read(ppd, QSFP_LOT_OFFS, &cp->lot, QSFP_LOT_LEN);
0407 if (ret < 0)
0408 goto bail;
0409 for (idx = 0; idx < QSFP_LOT_LEN; ++idx)
0410 cks += cp->lot[idx];
0411
0412 ret = qsfp_cks(ppd, QSFP_LOT_OFFS + QSFP_LOT_LEN, QSFP_CC_EXT_OFFS);
0413 if (ret < 0)
0414 goto bail;
0415 cks += ret;
0416
0417 ret = qsfp_read(ppd, QSFP_CC_EXT_OFFS, &cp->cks2, 1);
0418 if (ret < 0)
0419 goto bail;
0420 cks &= 0xFF;
0421 if (cks != cp->cks2)
0422 qib_dev_porterr(ppd->dd, ppd->port,
0423 "QSFP cks2 is %02X, computed %02X\n", cp->cks2,
0424 cks);
0425 return 0;
0426
0427 bail:
0428 cp->id = 0;
0429 return ret;
0430 }
0431
0432 const char * const qib_qsfp_devtech[16] = {
0433 "850nm VCSEL", "1310nm VCSEL", "1550nm VCSEL", "1310nm FP",
0434 "1310nm DFB", "1550nm DFB", "1310nm EML", "1550nm EML",
0435 "Cu Misc", "1490nm DFB", "Cu NoEq", "Cu Eq",
0436 "Undef", "Cu Active BothEq", "Cu FarEq", "Cu NearEq"
0437 };
0438
0439 #define QSFP_DUMP_CHUNK 16
0440 #define QSFP_DEFAULT_HDR_CNT 224
0441
0442 static const char *pwr_codes = "1.5W2.0W2.5W3.5W";
0443
0444 int qib_qsfp_mod_present(struct qib_pportdata *ppd)
0445 {
0446 u32 mask;
0447 int ret;
0448
0449 mask = QSFP_GPIO_MOD_PRS_N <<
0450 (ppd->hw_pidx * QSFP_GPIO_PORT2_SHIFT);
0451 ret = ppd->dd->f_gpio_mod(ppd->dd, 0, 0, 0);
0452
0453 return !((ret & mask) >>
0454 ((ppd->hw_pidx * QSFP_GPIO_PORT2_SHIFT) + 3));
0455 }
0456
0457
0458
0459
0460
0461 void qib_qsfp_init(struct qib_qsfp_data *qd,
0462 void (*fevent)(struct work_struct *))
0463 {
0464 u32 mask, highs;
0465
0466 struct qib_devdata *dd = qd->ppd->dd;
0467
0468
0469 INIT_WORK(&qd->work, fevent);
0470
0471
0472
0473
0474
0475
0476 mask = QSFP_GPIO_MOD_SEL_N | QSFP_GPIO_MOD_RST_N | QSFP_GPIO_LP_MODE;
0477 highs = mask - QSFP_GPIO_MOD_RST_N;
0478 if (qd->ppd->hw_pidx) {
0479 mask <<= QSFP_GPIO_PORT2_SHIFT;
0480 highs <<= QSFP_GPIO_PORT2_SHIFT;
0481 }
0482 dd->f_gpio_mod(dd, highs, mask, mask);
0483 udelay(20);
0484
0485 dd->f_gpio_mod(dd, mask, mask, mask);
0486 }
0487
0488 int qib_qsfp_dump(struct qib_pportdata *ppd, char *buf, int len)
0489 {
0490 struct qib_qsfp_cache cd;
0491 u8 bin_buff[QSFP_DUMP_CHUNK];
0492 char lenstr[6];
0493 int sofar, ret;
0494 int bidx = 0;
0495
0496 sofar = 0;
0497 ret = qib_refresh_qsfp_cache(ppd, &cd);
0498 if (ret < 0)
0499 goto bail;
0500
0501 lenstr[0] = ' ';
0502 lenstr[1] = '\0';
0503 if (QSFP_IS_CU(cd.tech))
0504 sprintf(lenstr, "%dM ", cd.len);
0505
0506 sofar += scnprintf(buf + sofar, len - sofar, "PWR:%.3sW\n", pwr_codes +
0507 (QSFP_PWR(cd.pwr) * 4));
0508
0509 sofar += scnprintf(buf + sofar, len - sofar, "TECH:%s%s\n", lenstr,
0510 qib_qsfp_devtech[cd.tech >> 4]);
0511
0512 sofar += scnprintf(buf + sofar, len - sofar, "Vendor:%.*s\n",
0513 QSFP_VEND_LEN, cd.vendor);
0514
0515 sofar += scnprintf(buf + sofar, len - sofar, "OUI:%06X\n",
0516 QSFP_OUI(cd.oui));
0517
0518 sofar += scnprintf(buf + sofar, len - sofar, "Part#:%.*s\n",
0519 QSFP_PN_LEN, cd.partnum);
0520 sofar += scnprintf(buf + sofar, len - sofar, "Rev:%.*s\n",
0521 QSFP_REV_LEN, cd.rev);
0522 if (QSFP_IS_CU(cd.tech))
0523 sofar += scnprintf(buf + sofar, len - sofar, "Atten:%d, %d\n",
0524 QSFP_ATTEN_SDR(cd.atten),
0525 QSFP_ATTEN_DDR(cd.atten));
0526 sofar += scnprintf(buf + sofar, len - sofar, "Serial:%.*s\n",
0527 QSFP_SN_LEN, cd.serial);
0528 sofar += scnprintf(buf + sofar, len - sofar, "Date:%.*s\n",
0529 QSFP_DATE_LEN, cd.date);
0530 sofar += scnprintf(buf + sofar, len - sofar, "Lot:%.*s\n",
0531 QSFP_LOT_LEN, cd.lot);
0532
0533 while (bidx < QSFP_DEFAULT_HDR_CNT) {
0534 int iidx;
0535
0536 ret = qsfp_read(ppd, bidx, bin_buff, QSFP_DUMP_CHUNK);
0537 if (ret < 0)
0538 goto bail;
0539 for (iidx = 0; iidx < ret; ++iidx) {
0540 sofar += scnprintf(buf + sofar, len-sofar, " %02X",
0541 bin_buff[iidx]);
0542 }
0543 sofar += scnprintf(buf + sofar, len - sofar, "\n");
0544 bidx += QSFP_DUMP_CHUNK;
0545 }
0546 ret = sofar;
0547 bail:
0548 return ret;
0549 }