From 44c9c2da5edd22183ac8c7abc98efbaa7cb5ea12 Mon Sep 17 00:00:00 2001 From: Stephan de Wit Date: Fri, 9 Aug 2024 10:26:21 +0000 Subject: [PATCH] axgbe: Implement ifdi_i2c_req for diagnostics information Fixes https://github.com/opnsense/src/issues/178 --- sys/dev/axgbe/if_axgbe_pci.c | 11 ++++++++ sys/dev/axgbe/xgbe-phy-v2.c | 52 ++++++++++++++++-------------------- sys/dev/axgbe/xgbe.h | 3 ++- 3 files changed, 36 insertions(+), 30 deletions(-) diff --git a/sys/dev/axgbe/if_axgbe_pci.c b/sys/dev/axgbe/if_axgbe_pci.c index 6d8a1fdbb58..a25ee88d600 100644 --- a/sys/dev/axgbe/if_axgbe_pci.c +++ b/sys/dev/axgbe/if_axgbe_pci.c @@ -108,6 +108,7 @@ static int axgbe_if_promisc_set(if_ctx_t, int); static uint64_t axgbe_if_get_counter(if_ctx_t, ift_counter); static void axgbe_if_vlan_register(if_ctx_t, uint16_t); static void axgbe_if_vlan_unregister(if_ctx_t, uint16_t); +static int axgbe_if_i2c_req(if_ctx_t, struct ifi2creq *); #if __FreeBSD_version >= 1300000 static bool axgbe_if_needs_restart(if_ctx_t, enum iflib_restart_event); #endif @@ -235,6 +236,7 @@ static device_method_t axgbe_if_methods[] = { DEVMETHOD(ifdi_get_counter, axgbe_if_get_counter), DEVMETHOD(ifdi_vlan_register, axgbe_if_vlan_register), DEVMETHOD(ifdi_vlan_unregister, axgbe_if_vlan_unregister), + DEVMETHOD(ifdi_i2c_req, axgbe_if_i2c_req), #if __FreeBSD_version >= 1300000 DEVMETHOD(ifdi_needs_restart, axgbe_if_needs_restart), #endif @@ -1904,6 +1906,15 @@ axgbe_if_vlan_unregister(if_ctx_t ctx, uint16_t vtag) xgbe_dump_active_vlans(pdata); } +static int +axgbe_if_i2c_req(if_ctx_t ctx, struct ifi2creq *req) +{ + struct axgbe_if_softc *sc = iflib_get_softc(ctx); + struct xgbe_prv_data *pdata = &sc->pdata; + + return pdata->phy_if.phy_impl.module_eeprom(pdata, req->dev_addr, req->offset, req->data, req->len); +} + #if __FreeBSD_version >= 1300000 static bool axgbe_if_needs_restart(if_ctx_t ctx __unused, enum iflib_restart_event event) diff --git a/sys/dev/axgbe/xgbe-phy-v2.c b/sys/dev/axgbe/xgbe-phy-v2.c index 43f2f7f08c5..8a9d0bbcb31 100644 --- a/sys/dev/axgbe/xgbe-phy-v2.c +++ b/sys/dev/axgbe/xgbe-phy-v2.c @@ -1840,63 +1840,57 @@ put: } static int -xgbe_phy_module_eeprom(struct xgbe_prv_data *pdata) +xgbe_phy_module_eeprom(struct xgbe_prv_data *pdata, uint16_t dev_addr, + uint16_t offset, uint8_t *data, uint16_t length) { struct xgbe_phy_data *phy_data = pdata->phy_data; - uint8_t eeprom_addr, eeprom_data[XGBE_SFP_EEPROM_MAX]; - struct xgbe_sfp_eeprom *sfp_eeprom; + uint8_t eeprom_addr; + unsigned int target; int ret; if (phy_data->port_mode != XGBE_PORT_MODE_SFP) { - ret = -ENXIO; + ret = (ENXIO); goto done; } if (phy_data->sfp_mod_absent) { - ret = -EIO; + ret = (EIO); goto done; } + if ((offset + length) > XGBE_SFP_EEPROM_MAX) { + ret = (EINVAL); + } + + if (!length || length > 16) { + return (EINVAL); + } + + target = dev_addr == 0xA0 ? XGBE_SFP_SERIAL_ID_ADDRESS : + XGBE_SFP_DIAG_INFO_ADDRESS; + ret = xgbe_phy_get_comm_ownership(pdata); if (ret) { - ret = -EIO; + ret = (EIO); goto done; } ret = xgbe_phy_sfp_get_mux(pdata); if (ret) { axgbe_error("I2C error setting SFP MUX\n"); - ret = -EIO; + ret = (EIO); goto put_own; } - /* Read the SFP serial ID eeprom */ - eeprom_addr = 0; - ret = xgbe_phy_i2c_read(pdata, XGBE_SFP_SERIAL_ID_ADDRESS, - &eeprom_addr, sizeof(eeprom_addr), - eeprom_data, XGBE_SFP_EEPROM_BASE_LEN); + eeprom_addr = offset; + ret = xgbe_phy_i2c_read(pdata, target, &eeprom_addr, sizeof(eeprom_addr), + (void *)data, length); if (ret) { axgbe_error("I2C error reading SFP EEPROM\n"); - ret = -EIO; + ret = (EIO); goto put_mux; } - sfp_eeprom = (struct xgbe_sfp_eeprom *)eeprom_data; - - if (XGBE_SFP_DIAGS_SUPPORTED(sfp_eeprom)) { - /* Read the SFP diagnostic eeprom */ - eeprom_addr = 0; - ret = xgbe_phy_i2c_read(pdata, XGBE_SFP_DIAG_INFO_ADDRESS, - &eeprom_addr, sizeof(eeprom_addr), - eeprom_data + XGBE_SFP_EEPROM_BASE_LEN, - XGBE_SFP_EEPROM_DIAG_LEN); - if (ret) { - axgbe_error("I2C error reading SFP DIAGS\n"); - ret = -EIO; - goto put_mux; - } - } - put_mux: xgbe_phy_sfp_put_mux(pdata); diff --git a/sys/dev/axgbe/xgbe.h b/sys/dev/axgbe/xgbe.h index f45d181e2de..4d3b56af458 100644 --- a/sys/dev/axgbe/xgbe.h +++ b/sys/dev/axgbe/xgbe.h @@ -904,7 +904,8 @@ struct xgbe_phy_impl_if { /* SFP module related info */ int (*module_info)(struct xgbe_prv_data *pdata); - int (*module_eeprom)(struct xgbe_prv_data *pdata); + int (*module_eeprom)(struct xgbe_prv_data *pdata, uint16_t, uint16_t, + uint8_t *, uint16_t); /* Drive LED status */ void (*toggle_led)(struct xgbe_prv_data *pdata, enum xgbe_led_mode);