Page MenuHomeFreeBSD

D42958.id131127.diff
No OneTemporary

D42958.id131127.diff

Index: bnxt.h
===================================================================
--- bnxt.h
+++ bnxt.h
@@ -319,6 +319,8 @@
#define BNXT_AUTONEG_FLOW_CTRL 2
uint8_t req_duplex;
uint16_t req_link_speed;
+ uint8_t module_status;
+ struct hwrm_port_phy_qcfg_output phy_qcfg_resp;
};
enum bnxt_cp_type {
@@ -802,9 +804,15 @@
uint64_t l2_filter_id_hint;
};
+#define I2C_DEV_ADDR_A0 0xa0
+#define BNXT_MAX_PHY_I2C_RESP_SIZE 64
+
/* Function declarations */
void bnxt_report_link(struct bnxt_softc *softc);
bool bnxt_check_hwrm_version(struct bnxt_softc *softc);
struct bnxt_softc *bnxt_find_dev(uint32_t domain, uint32_t bus, uint32_t dev_fn, char *name);
+int bnxt_read_sfp_module_eeprom_info(struct bnxt_softc *bp, uint16_t i2c_addr,
+ uint16_t page_number, uint8_t bank, bool bank_sel_en, uint16_t start_addr,
+ uint16_t data_length, uint8_t *buf);
#endif /* _BNXT_H */
Index: bnxt_hwrm.c
===================================================================
--- bnxt_hwrm.c
+++ bnxt_hwrm.c
@@ -2184,6 +2184,44 @@
return hwrm_send_message(softc, &req, sizeof(req));
}
+int bnxt_read_sfp_module_eeprom_info(struct bnxt_softc *softc, uint16_t i2c_addr,
+ uint16_t page_number, uint8_t bank,bool bank_sel_en, uint16_t start_addr,
+ uint16_t data_length, uint8_t *buf)
+{
+ struct hwrm_port_phy_i2c_read_output *output =
+ (void *)softc->hwrm_cmd_resp.idi_vaddr;
+ struct hwrm_port_phy_i2c_read_input req = {0};
+ int rc = 0, byte_offset = 0;
+
+ BNXT_HWRM_LOCK(softc);
+ bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_PORT_PHY_I2C_READ);
+
+ req.i2c_slave_addr = i2c_addr;
+ req.page_number = htole16(page_number);
+ req.port_id = htole16(softc->pf.port_id);
+ do {
+ uint16_t xfer_size;
+
+ xfer_size = min_t(uint16_t, data_length, BNXT_MAX_PHY_I2C_RESP_SIZE);
+ data_length -= xfer_size;
+ req.page_offset = htole16(start_addr + byte_offset);
+ req.data_length = xfer_size;
+ req.bank_number = bank;
+ req.enables = htole32((start_addr + byte_offset ?
+ HWRM_PORT_PHY_I2C_READ_INPUT_ENABLES_PAGE_OFFSET : 0) |
+ (bank_sel_en ?
+ HWRM_PORT_PHY_I2C_READ_INPUT_ENABLES_BANK_NUMBER : 0));
+ rc = hwrm_send_message(softc, &req, sizeof(req));
+ if (!rc)
+ memcpy(buf + byte_offset, output->data, xfer_size);
+ byte_offset += xfer_size;
+ } while (!rc && data_length > 0);
+
+ BNXT_HWRM_UNLOCK(softc);
+
+ return rc;
+}
+
int
bnxt_hwrm_port_phy_qcfg(struct bnxt_softc *softc)
{
@@ -2200,6 +2238,7 @@
if (rc)
goto exit;
+ memcpy(&link_info->phy_qcfg_resp, resp, sizeof(*resp));
link_info->phy_link_status = resp->link;
link_info->duplex = resp->duplex_cfg;
link_info->auto_mode = resp->auto_mode;
@@ -2264,6 +2303,7 @@
link_info->transceiver = resp->xcvr_pkg_type;
link_info->phy_addr = resp->eee_config_phy_addr &
HWRM_PORT_PHY_QCFG_OUTPUT_PHY_ADDR_MASK;
+ link_info->module_status = resp->module_status;
exit:
BNXT_HWRM_UNLOCK(softc);
Index: if_bnxt.c
===================================================================
--- if_bnxt.c
+++ if_bnxt.c
@@ -225,6 +225,8 @@
static void bnxt_get_wol_settings(struct bnxt_softc *softc);
static int bnxt_wol_config(if_ctx_t ctx);
static bool bnxt_if_needs_restart(if_ctx_t, enum iflib_restart_event);
+static int bnxt_i2c_req(if_ctx_t ctx, struct ifi2creq *i2c);
+static void bnxt_get_port_module_status(struct bnxt_softc *softc);
/*
* Device Interface Declaration
@@ -288,6 +290,7 @@
DEVMETHOD(ifdi_suspend, bnxt_suspend),
DEVMETHOD(ifdi_shutdown, bnxt_shutdown),
DEVMETHOD(ifdi_resume, bnxt_resume),
+ DEVMETHOD(ifdi_i2c_req, bnxt_i2c_req),
DEVMETHOD(ifdi_needs_restart, bnxt_if_needs_restart),
@@ -1808,6 +1811,33 @@
}
}
+static void bnxt_get_port_module_status(struct bnxt_softc *softc)
+{
+ struct bnxt_link_info *link_info = &softc->link_info;
+ struct hwrm_port_phy_qcfg_output *resp = &link_info->phy_qcfg_resp;
+ uint8_t module_status;
+
+ if (bnxt_update_link(softc, false))
+ return;
+
+ module_status = link_info->module_status;
+ switch (module_status) {
+ case HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_DISABLETX:
+ case HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_PWRDOWN:
+ case HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_WARNINGMSG:
+ device_printf(softc->dev, "Unqualified SFP+ module detected on port %d\n",
+ softc->pf.port_id);
+ if (softc->hwrm_spec_code >= 0x10201) {
+ device_printf(softc->dev, "Module part number %s\n",
+ resp->phy_vendor_partnumber);
+ }
+ if (module_status == HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_DISABLETX)
+ device_printf(softc->dev, "TX is disabled\n");
+ if (module_status == HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_PWRDOWN)
+ device_printf(softc->dev, "SFP+ module is shutdown\n");
+ }
+}
+
/* Device configuration */
static void
bnxt_init(if_ctx_t ctx)
@@ -1970,6 +2000,7 @@
}
bnxt_do_enable_intr(&softc->def_cp_ring);
+ bnxt_get_port_module_status(softc);
bnxt_media_status(softc->ctx, &ifmr);
bnxt_hwrm_cfa_l2_set_rx_mask(softc, &softc->vnic_info);
return;
@@ -2899,6 +2930,33 @@
return rc;
}
+static int
+bnxt_i2c_req(if_ctx_t ctx, struct ifi2creq *i2c)
+{
+ struct bnxt_softc *softc = iflib_get_softc(ctx);
+ uint8_t *data = i2c->data;
+ 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 (softc->link_info.module_status >
+ HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_WARNINGMSG)
+ return -EOPNOTSUPP;
+
+ /* This feature is not supported in older firmware versions */
+ if (!BNXT_CHIP_P5(softc) ||
+ (softc->hwrm_spec_code < 0x10202))
+ return -EOPNOTSUPP;
+
+
+ rc = bnxt_read_sfp_module_eeprom_info(softc, I2C_DEV_ADDR_A0, 0, 0, 0,
+ i2c->offset, i2c->len, data);
+
+ return rc;
+}
+
/*
* Support functions
*/
@@ -2915,6 +2973,7 @@
return (rc);
}
+ bnxt_get_port_module_status(softc);
/*initialize the ethool setting copy with NVM settings */
if (link_info->auto_mode != HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_NONE)
link_info->autoneg |= BNXT_AUTONEG_SPEED;

File Metadata

Mime Type
text/plain
Expires
Tue, May 19, 1:19 PM (10 h, 43 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33313296
Default Alt Text
D42958.id131127.diff (5 KB)

Event Timeline