void printSffDetail()

in fboss/util/wedge_qsfp_util.cpp [1592:1810]


void printSffDetail(const DOMDataUnion& domDataUnion, unsigned int port) {
  Sff8636Data sffData = domDataUnion.get_sff8636();
  auto lowerBuf = sffData.lower()->data();
  auto page0Buf = sffData.page0()->data();

  printf("Port %d\n", port);
  printf("  ID: %#04x\n", lowerBuf[0]);
  printf("  Status: 0x%02x 0x%02x\n", lowerBuf[1], lowerBuf[2]);
  printf("  Module State: 0x%02x\n", lowerBuf[3]);
  printf(
      "  EEPROM Checksum: %s\n",
      getEepromCsumStatus(domDataUnion) ? "Valid" : "Invalid");

  printf("  Interrupt Flags:\n");
  printf("    LOS: 0x%02x\n", lowerBuf[3]);
  printf("    Fault: 0x%02x\n", lowerBuf[4]);
  printf("    LOL: 0x%02x\n", lowerBuf[5]);
  printf("    Temp: 0x%02x\n", lowerBuf[6]);
  printf("    Vcc: 0x%02x\n", lowerBuf[7]);
  printf("    Rx Power: 0x%02x 0x%02x\n", lowerBuf[9], lowerBuf[10]);
  printf("    Tx Power: 0x%02x 0x%02x\n", lowerBuf[13], lowerBuf[14]);
  printf("    Tx Bias: 0x%02x 0x%02x\n", lowerBuf[11], lowerBuf[12]);
  printf("    Reserved Set 4: 0x%02x 0x%02x\n", lowerBuf[15], lowerBuf[16]);
  printf("    Reserved Set 5: 0x%02x 0x%02x\n", lowerBuf[17], lowerBuf[18]);
  printf(
      "    Vendor Defined: 0x%02x 0x%02x 0x%02x\n",
      lowerBuf[19],
      lowerBuf[20],
      lowerBuf[21]);

  auto temp = static_cast<int8_t>(lowerBuf[22]) + (lowerBuf[23] / 256.0);
  printf("  Temperature: %f C\n", temp);
  uint16_t voltage = (lowerBuf[26] << 8) | lowerBuf[27];
  printf("  Supply Voltage: %f V\n", voltage / 10000.0);

  printf(
      "  Channel Data:  %12s    %12s    %12s    %12s\n",
      "RX Power",
      "TX Power",
      "TX Bias",
      "Rx SNR");
  printChannelMonitor(1, lowerBuf, 34, 35, 42, 43, 50, 51);
  printChannelMonitor(2, lowerBuf, 36, 37, 44, 45, 52, 53);
  printChannelMonitor(3, lowerBuf, 38, 39, 46, 47, 54, 55);
  printChannelMonitor(4, lowerBuf, 40, 41, 48, 49, 56, 57);
  printf(
      "    Power measurement is %s\n",
      (page0Buf[92] & 0x04) ? "supported" : "unsupported");
  printf(
      "    Reported RX Power is %s\n",
      (page0Buf[92] & 0x08) ? "average power" : "OMA");

  printf(
      "  Power set:  0x%02x\tExtended ID:  0x%02x\t"
      "Ethernet Compliance:  0x%02x\n",
      lowerBuf[93],
      page0Buf[1],
      page0Buf[3]);
  printf("  TX disable bits: 0x%02x\n", lowerBuf[86]);
  printf(
      "  Rate select is %s\n",
      (page0Buf[93] & 0x0c) ? "supported" : "unsupported");
  printf("  RX rate select bits: 0x%02x\n", lowerBuf[87]);
  printf("  TX rate select bits: 0x%02x\n", lowerBuf[88]);
  printf(
      "  CDR support:  TX: %s\tRX: %s\n",
      (page0Buf[1] & (1 << 3)) ? "supported" : "unsupported",
      (page0Buf[1] & (1 << 2)) ? "supported" : "unsupported");
  printf("  CDR bits: 0x%02x\n", lowerBuf[98]);

  auto vendor = sfpString(page0Buf, 20, 16);
  auto vendorPN = sfpString(page0Buf, 40, 16);
  auto vendorRev = sfpString(page0Buf, 56, 2);
  auto vendorSN = sfpString(page0Buf, 68, 16);
  auto vendorDate = sfpString(page0Buf, 84, 8);

  int gauge = page0Buf[109];
  auto cableGauge = gauge;
  if (gauge == eePromDefault && gauge > maxGauge) {
    // gauge implemented as hexadecimal (why?). Convert to decimal
    cableGauge = (gauge / hexBase) * decimalBase + gauge % hexBase;
  } else {
    cableGauge = 0;
  }

  printf("  Connector: 0x%02x\n", page0Buf[2]);
  printf(
      "  Spec compliance: "
      "0x%02x 0x%02x 0x%02x 0x%02x"
      "0x%02x 0x%02x 0x%02x 0x%02x\n",
      page0Buf[3],
      page0Buf[4],
      page0Buf[5],
      page0Buf[6],
      page0Buf[7],
      page0Buf[8],
      page0Buf[9],
      page0Buf[10]);
  printf("  Encoding: 0x%02x\n", page0Buf[11]);
  printf("  Nominal Bit Rate: %d MBps\n", page0Buf[12] * 100);
  printf("  Ext rate select compliance: 0x%02x\n", page0Buf[13]);
  printf("  Length (SMF): %d km\n", page0Buf[14]);
  printf("  Length (OM3): %d m\n", page0Buf[15] * 2);
  printf("  Length (OM2): %d m\n", page0Buf[16]);
  printf("  Length (OM1): %d m\n", page0Buf[17]);
  printf("  Length (Copper): %d m\n", page0Buf[18]);
  if (page0Buf[108] != eePromDefault) {
    auto fractional = page0Buf[108] * .1;
    auto effective = fractional >= 1 ? fractional : page0Buf[18];
    printf("  Length (Copper dM): %.1f m\n", fractional);
    printf("  Length (Copper effective): %.1f m\n", effective);
  }
  if (cableGauge > 0) {
    printf("  DAC Cable Gauge: %d\n", cableGauge);
  }
  printf("  Device Tech: 0x%02x\n", page0Buf[19]);
  printf("  Ext Module: 0x%02x\n", page0Buf[36]);
  printf("  Wavelength tolerance: 0x%02x 0x%02x\n", page0Buf[60], page0Buf[61]);
  printf("  Max case temp: %dC\n", page0Buf[62]);
  printf("  CC_BASE: 0x%02x\n", page0Buf[63]);
  printf(
      "  Options: 0x%02x 0x%02x 0x%02x 0x%02x\n",
      page0Buf[64],
      page0Buf[65],
      page0Buf[66],
      page0Buf[67]);
  printf("  DOM Type: 0x%02x\n", page0Buf[92]);
  printf("  Enhanced Options: 0x%02x\n", page0Buf[93]);
  printf("  Reserved: 0x%02x\n", page0Buf[94]);
  printf("  CC_EXT: 0x%02x\n", page0Buf[95]);
  printf("  Vendor Specific:\n");
  printf(
      "    %02x %02x %02x %02x %02x %02x %02x %02x"
      "  %02x %02x %02x %02x %02x %02x %02x %02x\n",
      page0Buf[96],
      page0Buf[97],
      page0Buf[98],
      page0Buf[99],
      page0Buf[100],
      page0Buf[101],
      page0Buf[102],
      page0Buf[103],
      page0Buf[104],
      page0Buf[105],
      page0Buf[106],
      page0Buf[107],
      page0Buf[108],
      page0Buf[109],
      page0Buf[110],
      page0Buf[111]);
  printf(
      "    %02x %02x %02x %02x %02x %02x %02x %02x"
      "  %02x %02x %02x %02x %02x %02x %02x %02x\n",
      page0Buf[112],
      page0Buf[113],
      page0Buf[114],
      page0Buf[115],
      page0Buf[116],
      page0Buf[117],
      page0Buf[118],
      page0Buf[119],
      page0Buf[120],
      page0Buf[121],
      page0Buf[122],
      page0Buf[123],
      page0Buf[124],
      page0Buf[125],
      page0Buf[126],
      page0Buf[127]);

  printf("  Vendor: %s\n", vendor.str().c_str());
  printf(
      "  Vendor OUI: %02x:%02x:%02x\n",
      lowerBuf[165 - 128],
      lowerBuf[166 - 128],
      lowerBuf[167 - 128]);
  printf("  Vendor PN: %s\n", vendorPN.str().c_str());
  printf("  Vendor Rev: %s\n", vendorRev.str().c_str());
  printf("  Vendor SN: %s\n", vendorSN.str().c_str());
  printf("  Date Code: %s\n", vendorDate.str().c_str());

  // print page3 values
  if (!sffData.page3()) {
    return;
  }

  auto page3Buf = sffData.page3().value_unchecked().data();

  printThresholds("Temp", &page3Buf[0], [](const uint16_t u16_temp) {
    double data;
    data = u16_temp / 256.0;
    if (data > 128) {
      data = data - 256;
    }
    return data;
  });

  printThresholds("Vcc", &page3Buf[16], [](const uint16_t u16_vcc) {
    double data;
    data = u16_vcc / 10000.0;
    return data;
  });

  printThresholds("Rx Power", &page3Buf[48], [](const uint16_t u16_rxpwr) {
    double data;
    data = u16_rxpwr * 0.1 / 1000;
    return data;
  });

  printThresholds("Tx Bias", &page3Buf[56], [](const uint16_t u16_txbias) {
    double data;
    data = u16_txbias * 2.0 / 1000;
    return data;
  });

  if (auto timeCollected = sffData.timeCollected()) {
    printf("  Time collected: %s\n", getLocalTime(*timeCollected).c_str());
  }
}