+ uint8_t index, dir_op;
+ uint16_t type, ext, ordinal, attr;
+ int rc;
+
+ rc = is_bnxt_in_error(bp);
+ if (rc)
+ return rc;
+
+ PMD_DRV_LOG(INFO, PCI_PRI_FMT " in_eeprom->offset = %d len = %d\n",
+ bp->pdev->addr.domain, bp->pdev->addr.bus,
+ bp->pdev->addr.devid, bp->pdev->addr.function,
+ in_eeprom->offset, in_eeprom->length);
+
+ if (!BNXT_PF(bp)) {
+ PMD_DRV_LOG(ERR, "NVM write not supported from a VF\n");
+ return -EINVAL;
+ }
+
+ type = in_eeprom->magic >> 16;
+
+ if (type == 0xffff) { /* special value for directory operations */
+ index = in_eeprom->magic & 0xff;
+ dir_op = in_eeprom->magic >> 8;
+ if (index == 0)
+ return -EINVAL;
+ switch (dir_op) {
+ case 0x0e: /* erase */
+ if (in_eeprom->offset != ~in_eeprom->magic)
+ return -EINVAL;
+ return bnxt_hwrm_erase_nvram_directory(bp, index - 1);
+ default:
+ return -EINVAL;
+ }
+ }
+
+ /* Create or re-write an NVM item: */
+ if (bnxt_dir_type_is_executable(type) == true)
+ return -EOPNOTSUPP;
+ ext = in_eeprom->magic & 0xffff;
+ ordinal = in_eeprom->offset >> 16;
+ attr = in_eeprom->offset & 0xffff;
+
+ return bnxt_hwrm_flash_nvram(bp, type, ordinal, ext, attr,
+ in_eeprom->data, in_eeprom->length);
+}
+
+static int bnxt_get_module_info(struct rte_eth_dev *dev,
+ struct rte_eth_dev_module_info *modinfo)
+{
+ uint8_t module_info[SFF_DIAG_SUPPORT_OFFSET + 1];
+ struct bnxt *bp = dev->data->dev_private;
+ int rc;
+
+ /* No point in going further if phy status indicates
+ * module is not inserted or if it is powered down or
+ * if it is of type 10GBase-T
+ */
+ if (bp->link_info->module_status >
+ HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_WARNINGMSG) {
+ PMD_DRV_LOG(NOTICE, "Port %u : Module is not inserted or is powered down\n",
+ dev->data->port_id);
+ return -ENOTSUP;
+ }
+
+ /* This feature is not supported in older firmware versions */
+ if (bp->hwrm_spec_code < 0x10202) {
+ PMD_DRV_LOG(NOTICE, "Port %u : Feature is not supported in older firmware\n",
+ dev->data->port_id);
+ return -ENOTSUP;
+ }
+
+ rc = bnxt_hwrm_read_sfp_module_eeprom_info(bp, I2C_DEV_ADDR_A0, 0, 0,
+ SFF_DIAG_SUPPORT_OFFSET + 1,
+ module_info);
+
+ if (rc)
+ return rc;
+
+ switch (module_info[0]) {
+ case SFF_MODULE_ID_SFP:
+ modinfo->type = RTE_ETH_MODULE_SFF_8472;
+ modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8472_LEN;
+ if (module_info[SFF_DIAG_SUPPORT_OFFSET] == 0)
+ modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8436_LEN;
+ break;
+ case SFF_MODULE_ID_QSFP:
+ case SFF_MODULE_ID_QSFP_PLUS:
+ modinfo->type = RTE_ETH_MODULE_SFF_8436;
+ modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8436_LEN;
+ break;
+ case SFF_MODULE_ID_QSFP28:
+ modinfo->type = RTE_ETH_MODULE_SFF_8636;
+ modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8636_MAX_LEN;
+ if (module_info[SFF8636_FLATMEM_OFFSET] & SFF8636_FLATMEM_MASK)
+ modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8636_LEN;
+ break;
+ default:
+ PMD_DRV_LOG(NOTICE, "Port %u : Unsupported module\n", dev->data->port_id);
+ return -ENOTSUP;
+ }
+
+ PMD_DRV_LOG(INFO, "Port %u : modinfo->type = %d modinfo->eeprom_len = %d\n",
+ dev->data->port_id, modinfo->type, modinfo->eeprom_len);
+
+ return 0;
+}
+
+static int bnxt_get_module_eeprom(struct rte_eth_dev *dev,
+ struct rte_dev_eeprom_info *info)
+{
+ uint8_t pg_addr[5] = { I2C_DEV_ADDR_A0, I2C_DEV_ADDR_A0 };
+ uint32_t offset = info->offset, length = info->length;
+ uint8_t module_info[SFF_DIAG_SUPPORT_OFFSET + 1];
+ struct bnxt *bp = dev->data->dev_private;
+ uint8_t *data = info->data;
+ uint8_t page = offset >> 7;
+ uint8_t max_pages = 2;
+ uint8_t opt_pages;