aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Petter Selasky <hselasky@FreeBSD.org>2019-10-02 10:14:55 +0000
committerHans Petter Selasky <hselasky@FreeBSD.org>2019-10-02 10:14:55 +0000
commit048ddb58bc5eeedba578dace633efbf1c6c2864a (patch)
treea247255ff307c1f23e6a777038c04bcd8330c62d
parent6deb0b1e94c6afc20ddbeed5c1336874612bc5d8 (diff)
downloadsrc-048ddb58bc5eeedba578dace633efbf1c6c2864a.tar.gz
src-048ddb58bc5eeedba578dace633efbf1c6c2864a.zip
Move EEPROM information query from a sysctl in mlx5en(4) to an ioctl
in mlx5core. The EEPROM information is not only a property of the mlx5en(4) driver. Submitted by: slavash@ MFC after: 3 days Sponsored by: Mellanox Technologies
Notes
Notes: svn path=/head/; revision=352983
-rw-r--r--share/man/man4/mlx5io.429
-rw-r--r--sys/dev/mlx5/diagnostics.h17
-rw-r--r--sys/dev/mlx5/mlx5_core/mlx5_diagnostics.c156
-rw-r--r--sys/dev/mlx5/mlx5_core/mlx5_fwdump.c63
-rw-r--r--sys/dev/mlx5/mlx5_en/en.h28
-rw-r--r--sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c213
-rw-r--r--sys/dev/mlx5/mlx5_en/mlx5_en_main.c8
-rw-r--r--sys/dev/mlx5/mlx5io.h8
-rw-r--r--sys/dev/mlx5/port.h27
9 files changed, 298 insertions, 251 deletions
diff --git a/share/man/man4/mlx5io.4 b/share/man/man4/mlx5io.4
index 8b30d17c76eb..5057ee356204 100644
--- a/share/man/man4/mlx5io.4
+++ b/share/man/man4/mlx5io.4
@@ -25,18 +25,18 @@
.\"
.\" $FreeBSD$
.\"
-.Dd May 7, 2019
+.Dd October 2, 2019
.Dt mlx5io 4
.Os
.Sh NAME
.Nm mlx5io
-.Nd IOCTL interface to manage Connect-X 4/5 Mellanox network adapters
+.Nd IOCTL interface to manage Connect-X 4/5/6 Mellanox network adapters
.Sh SYNOPSIS
.In dev/mlx5/mlx5io.h
.Sh DESCRIPTION
The
.Nm
-interface is provided for management of the Connect-X 4 and 5 network adapters
+interface is provided for management of the Connect-X4, 5 and 6 network adapters
in the aspects not covered by the generic network configuration,
mostly related to the PCIe attachment and internal card working.
Interface consists of the commands, which are passed by means of
@@ -147,6 +147,29 @@ Requests PCIe link-level reset on the device.
The address of the device is specified by the
.Vt struct mlx5_tool_addr
structure, which should be passed as an argument.
+.It Dv MLX5_EEPROM_GET
+Fetch EEPROM information.
+The argument to the command should point to the input/output
+.Vt struct mlx5_eeprom_get
+structure where, the
+.Dv devaddr
+field specifies the address of the device.
+.Bd -literal
+struct mlx5_eeprom_get {
+ struct mlx5_tool_addr devaddr;
+ size_t eeprom_info_page_valid;
+ uint32_t *eeprom_info_buf;
+ size_t eeprom_info_out_len;
+};
+.Ed
+.Pp
+On successfull return, the
+.Dv eeprom_info_out_len
+field reports the length of the EEPROM information.
+.Dv eeprom_info_buf
+field contains the actual EEPROM information.
+.Dv eeprom_info_page_valid
+field reports the third page validity.
.El
.Sh FILES
The
diff --git a/sys/dev/mlx5/diagnostics.h b/sys/dev/mlx5/diagnostics.h
index df5c6aa06243..1baa665fb432 100644
--- a/sys/dev/mlx5/diagnostics.h
+++ b/sys/dev/mlx5/diagnostics.h
@@ -32,6 +32,8 @@
#define MLX5_CORE_DIAGNOSTICS_STRUCT(n, s, t) s,
#define MLX5_CORE_DIAGNOSTICS_ENTRY(n, s, t) { #s, (t) },
+static MALLOC_DEFINE(M_MLX5_EEPROM, "MLX5EEPROM", "MLX5 EEPROM information");
+
struct mlx5_core_diagnostics_entry {
const char *desc;
u16 counter_id;
@@ -127,6 +129,18 @@ union mlx5_core_general_diagnostics {
extern const struct mlx5_core_diagnostics_entry
mlx5_core_general_diagnostics_table[MLX5_CORE_GENERAL_DIAGNOSTICS_NUM];
+struct mlx5_eeprom {
+ int lock_bit;
+ int i2c_addr;
+ int page_num;
+ int device_addr;
+ int module_num;
+ int len;
+ int type;
+ int page_valid;
+ u32 *data;
+};
+
/* function prototypes */
int mlx5_core_set_diagnostics_full(struct mlx5_core_dev *mdev,
u8 enable_pci, u8 enable_general);
@@ -134,5 +148,8 @@ int mlx5_core_get_diagnostics_full(struct mlx5_core_dev *mdev,
union mlx5_core_pci_diagnostics *ppci,
union mlx5_core_general_diagnostics *pgen);
int mlx5_core_supports_diagnostics(struct mlx5_core_dev *mdev, u16 counter_id);
+int mlx5_read_eeprom(struct mlx5_core_dev *dev, struct mlx5_eeprom *eeprom);
+int mlx5_get_eeprom_info(struct mlx5_core_dev *dev, struct mlx5_eeprom *eeprom);
+int mlx5_get_eeprom(struct mlx5_core_dev *dev, struct mlx5_eeprom *ee);
#endif /* MLX5_CORE_DIAGNOSTICS_H */
diff --git a/sys/dev/mlx5/mlx5_core/mlx5_diagnostics.c b/sys/dev/mlx5/mlx5_core/mlx5_diagnostics.c
index 592be19d9417..00740095b3e1 100644
--- a/sys/dev/mlx5/mlx5_core/mlx5_diagnostics.c
+++ b/sys/dev/mlx5/mlx5_core/mlx5_diagnostics.c
@@ -26,7 +26,10 @@
*/
#include <dev/mlx5/driver.h>
+#include <dev/mlx5/port.h>
#include <dev/mlx5/diagnostics.h>
+#include <dev/mlx5/mlx5_core/mlx5_core.h>
+#include <net/sff8472.h>
const struct mlx5_core_diagnostics_entry
mlx5_core_pci_diagnostics_table[
@@ -284,3 +287,156 @@ int mlx5_core_supports_diagnostics(struct mlx5_core_dev *dev, u16 counter_id)
}
return 0; /* not supported counter */
}
+
+/*
+ * Read the first three bytes of the eeprom in order to get the needed info
+ * for the whole reading.
+ * Byte 0 - Identifier byte
+ * Byte 1 - Revision byte
+ * Byte 2 - Status byte
+ */
+int
+mlx5_get_eeprom_info(struct mlx5_core_dev *dev, struct mlx5_eeprom *eeprom)
+{
+ u32 data = 0;
+ int size_read = 0;
+ int ret;
+
+ ret = mlx5_query_module_num(dev, &eeprom->module_num);
+ if (ret) {
+ mlx5_core_err(dev, "Failed query module error=%d\n", ret);
+ return (-ret);
+ }
+
+ /* Read the first three bytes to get Identifier, Revision and Status */
+ ret = mlx5_query_eeprom(dev, eeprom->i2c_addr, eeprom->page_num,
+ eeprom->device_addr, MLX5_EEPROM_INFO_BYTES, eeprom->module_num, &data,
+ &size_read);
+ if (ret) {
+ mlx5_core_err(dev,
+ "Failed query EEPROM module error=0x%x\n", ret);
+ return (-ret);
+ }
+
+ switch (data & MLX5_EEPROM_IDENTIFIER_BYTE_MASK) {
+ case SFF_8024_ID_QSFP:
+ eeprom->type = MLX5_ETH_MODULE_SFF_8436;
+ eeprom->len = MLX5_ETH_MODULE_SFF_8436_LEN;
+ break;
+ case SFF_8024_ID_QSFPPLUS:
+ case SFF_8024_ID_QSFP28:
+ if ((data & MLX5_EEPROM_IDENTIFIER_BYTE_MASK) == SFF_8024_ID_QSFP28 ||
+ ((data & MLX5_EEPROM_REVISION_ID_BYTE_MASK) >> 8) >= 0x3) {
+ eeprom->type = MLX5_ETH_MODULE_SFF_8636;
+ eeprom->len = MLX5_ETH_MODULE_SFF_8636_LEN;
+ } else {
+ eeprom->type = MLX5_ETH_MODULE_SFF_8436;
+ eeprom->len = MLX5_ETH_MODULE_SFF_8436_LEN;
+ }
+ if ((data & MLX5_EEPROM_PAGE_3_VALID_BIT_MASK) == 0)
+ eeprom->page_valid = 1;
+ break;
+ case SFF_8024_ID_SFP:
+ eeprom->type = MLX5_ETH_MODULE_SFF_8472;
+ eeprom->len = MLX5_ETH_MODULE_SFF_8472_LEN;
+ break;
+ default:
+ mlx5_core_err(dev, "Not recognized cable type = 0x%x(%s)\n",
+ data & MLX5_EEPROM_IDENTIFIER_BYTE_MASK,
+ sff_8024_id[data & MLX5_EEPROM_IDENTIFIER_BYTE_MASK]);
+ return (EINVAL);
+ }
+ return (0);
+}
+
+/* Read both low and high pages of the eeprom */
+int
+mlx5_get_eeprom(struct mlx5_core_dev *dev, struct mlx5_eeprom *ee)
+{
+ int size_read = 0;
+ int ret;
+
+ if (ee->len == 0)
+ return (EINVAL);
+
+ /* Read low page of the eeprom */
+ while (ee->device_addr < ee->len) {
+ ret = mlx5_query_eeprom(dev, ee->i2c_addr, ee->page_num, ee->device_addr,
+ ee->len - ee->device_addr, ee->module_num,
+ ee->data + (ee->device_addr / 4), &size_read);
+ if (ret) {
+ mlx5_core_err(dev,
+ "Failed reading EEPROM, error = 0x%02x\n", ret);
+ return (-ret);
+ }
+ ee->device_addr += size_read;
+ }
+
+ /* Read high page of the eeprom */
+ if (ee->page_valid == 1) {
+ ee->device_addr = MLX5_EEPROM_HIGH_PAGE_OFFSET;
+ ee->page_num = MLX5_EEPROM_HIGH_PAGE;
+ size_read = 0;
+ while (ee->device_addr < MLX5_EEPROM_PAGE_LENGTH) {
+ ret = mlx5_query_eeprom(dev, ee->i2c_addr, ee->page_num,
+ ee->device_addr, MLX5_EEPROM_PAGE_LENGTH - ee->device_addr,
+ ee->module_num, ee->data + (ee->len / 4) +
+ ((ee->device_addr - MLX5_EEPROM_HIGH_PAGE_OFFSET) / 4),
+ &size_read);
+ if (ret) {
+ mlx5_core_err(dev,
+ "Failed reading EEPROM, error = 0x%02x\n",
+ ret);
+ return (-ret);
+ }
+ ee->device_addr += size_read;
+ }
+ }
+ return (0);
+}
+
+/*
+ * Read cable EEPROM module information by first inspecting the first
+ * three bytes to get the initial information for a whole reading.
+ * Information will be printed to dmesg.
+ */
+int
+mlx5_read_eeprom(struct mlx5_core_dev *dev, struct mlx5_eeprom *eeprom)
+{
+ int error;
+
+ eeprom->i2c_addr = MLX5_I2C_ADDR_LOW;
+ eeprom->device_addr = 0;
+ eeprom->page_num = MLX5_EEPROM_LOW_PAGE;
+ eeprom->page_valid = 0;
+
+ /* Read three first bytes to get important info */
+ error = mlx5_get_eeprom_info(dev, eeprom);
+ if (error) {
+ mlx5_core_err(dev,
+ "Failed reading EEPROM initial information\n");
+ return (error);
+ }
+ /*
+ * Allocate needed length buffer and additional space for
+ * page 0x03
+ */
+ eeprom->data = malloc(eeprom->len + MLX5_EEPROM_PAGE_LENGTH,
+ M_MLX5_EEPROM, M_WAITOK | M_ZERO);
+
+ /* Read the whole eeprom information */
+ error = mlx5_get_eeprom(dev, eeprom);
+ if (error) {
+ mlx5_core_err(dev, "Failed reading EEPROM\n");
+ error = 0;
+ /*
+ * Continue printing partial information in case of
+ * an error
+ */
+ }
+ free(eeprom->data, M_MLX5_EEPROM);
+
+ return (error);
+}
+
+
diff --git a/sys/dev/mlx5/mlx5_core/mlx5_fwdump.c b/sys/dev/mlx5/mlx5_core/mlx5_fwdump.c
index 50f6ce884c47..eaf3ebbde7d5 100644
--- a/sys/dev/mlx5/mlx5_core/mlx5_fwdump.c
+++ b/sys/dev/mlx5/mlx5_core/mlx5_fwdump.c
@@ -32,8 +32,10 @@ __FBSDID("$FreeBSD$");
#include <sys/fcntl.h>
#include <dev/mlx5/driver.h>
#include <dev/mlx5/device.h>
+#include <dev/mlx5/port.h>
#include <dev/mlx5/mlx5_core/mlx5_core.h>
#include <dev/mlx5/mlx5io.h>
+#include <dev/mlx5/diagnostics.h>
static MALLOC_DEFINE(M_MLX5_DUMP, "MLX5DUMP", "MLX5 Firmware dump");
@@ -306,6 +308,54 @@ mlx5_fw_reset(struct mlx5_core_dev *mdev)
}
static int
+mlx5_eeprom_copyout(struct mlx5_core_dev *dev, struct mlx5_eeprom_get *eeprom_info)
+{
+ struct mlx5_eeprom eeprom;
+ int error;
+
+ eeprom.i2c_addr = MLX5_I2C_ADDR_LOW;
+ eeprom.device_addr = 0;
+ eeprom.page_num = MLX5_EEPROM_LOW_PAGE;
+ eeprom.page_valid = 0;
+
+ /* Read three first bytes to get important info */
+ error = mlx5_get_eeprom_info(dev, &eeprom);
+ if (error != 0) {
+ mlx5_core_err(dev,
+ "Failed reading EEPROM initial information\n");
+ return (error);
+ }
+ eeprom_info->eeprom_info_page_valid = eeprom.page_valid;
+ eeprom_info->eeprom_info_out_len = eeprom.len;
+
+ if (eeprom_info->eeprom_info_buf == NULL)
+ return (0);
+ /*
+ * Allocate needed length buffer and additional space for
+ * page 0x03
+ */
+ eeprom.data = malloc(eeprom.len + MLX5_EEPROM_PAGE_LENGTH,
+ M_MLX5_EEPROM, M_WAITOK | M_ZERO);
+
+ /* Read the whole eeprom information */
+ error = mlx5_get_eeprom(dev, &eeprom);
+ if (error != 0) {
+ mlx5_core_err(dev, "Failed reading EEPROM error = %d\n",
+ error);
+ error = 0;
+ /*
+ * Continue printing partial information in case of
+ * an error
+ */
+ }
+ error = copyout(eeprom.data, eeprom_info->eeprom_info_buf,
+ eeprom.len);
+ free(eeprom.data, M_MLX5_EEPROM);
+
+ return (error);
+}
+
+static int
mlx5_ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
struct thread *td)
{
@@ -314,6 +364,7 @@ mlx5_ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
struct mlx5_tool_addr *devaddr;
struct mlx5_fw_update *fu;
struct firmware fake_fw;
+ struct mlx5_eeprom_get *eeprom_info;
int error;
error = 0;
@@ -392,6 +443,18 @@ mlx5_ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
break;
error = mlx5_fw_reset(mdev);
break;
+ case MLX5_EEPROM_GET:
+ if ((fflag & FREAD) == 0) {
+ error = EBADF;
+ break;
+ }
+ eeprom_info = (struct mlx5_eeprom_get *)data;
+ devaddr = &eeprom_info->devaddr;
+ error = mlx5_dbsf_to_core(devaddr, &mdev);
+ if (error != 0)
+ break;
+ error = mlx5_eeprom_copyout(mdev, eeprom_info);
+ break;
default:
error = ENOTTY;
break;
diff --git a/sys/dev/mlx5/mlx5_en/en.h b/sys/dev/mlx5/mlx5_en/en.h
index 35a83f168666..4496caa3765e 100644
--- a/sys/dev/mlx5/mlx5_en/en.h
+++ b/sys/dev/mlx5/mlx5_en/en.h
@@ -714,34 +714,6 @@ struct mlx5e_params_ethtool {
u8 trust_state;
};
-/* EEPROM Standards for plug in modules */
-#ifndef MLX5E_ETH_MODULE_SFF_8472
-#define MLX5E_ETH_MODULE_SFF_8472 0x1
-#define MLX5E_ETH_MODULE_SFF_8472_LEN 128
-#endif
-
-#ifndef MLX5E_ETH_MODULE_SFF_8636
-#define MLX5E_ETH_MODULE_SFF_8636 0x2
-#define MLX5E_ETH_MODULE_SFF_8636_LEN 256
-#endif
-
-#ifndef MLX5E_ETH_MODULE_SFF_8436
-#define MLX5E_ETH_MODULE_SFF_8436 0x3
-#define MLX5E_ETH_MODULE_SFF_8436_LEN 256
-#endif
-
-/* EEPROM I2C Addresses */
-#define MLX5E_I2C_ADDR_LOW 0x50
-#define MLX5E_I2C_ADDR_HIGH 0x51
-
-#define MLX5E_EEPROM_LOW_PAGE 0x0
-#define MLX5E_EEPROM_HIGH_PAGE 0x3
-
-#define MLX5E_EEPROM_HIGH_PAGE_OFFSET 128
-#define MLX5E_EEPROM_PAGE_LENGTH 256
-
-#define MLX5E_EEPROM_INFO_BYTES 0x3
-
struct mlx5e_cq {
/* data path - accessed per cqe */
struct mlx5_cqwq wq;
diff --git a/sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c b/sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c
index 188609252480..7cb039bbf397 100644
--- a/sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c
+++ b/sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c
@@ -901,214 +901,6 @@ done:
return (error);
}
-/*
- * Read the first three bytes of the eeprom in order to get the needed info
- * for the whole reading.
- * Byte 0 - Identifier byte
- * Byte 1 - Revision byte
- * Byte 2 - Status byte
- */
-static int
-mlx5e_get_eeprom_info(struct mlx5e_priv *priv, struct mlx5e_eeprom *eeprom)
-{
- struct mlx5_core_dev *dev = priv->mdev;
- u32 data = 0;
- int size_read = 0;
- int ret;
-
- ret = mlx5_query_module_num(dev, &eeprom->module_num);
- if (ret) {
- mlx5_en_err(priv->ifp, "Failed query module error=%d\n",
- ret);
- return (ret);
- }
-
- /* Read the first three bytes to get Identifier, Revision and Status */
- ret = mlx5_query_eeprom(dev, eeprom->i2c_addr, eeprom->page_num,
- eeprom->device_addr, MLX5E_EEPROM_INFO_BYTES, eeprom->module_num, &data,
- &size_read);
- if (ret) {
- mlx5_en_err(priv->ifp,
- "Failed query eeprom module error=0x%x\n", ret);
- return (ret);
- }
-
- switch (data & MLX5_EEPROM_IDENTIFIER_BYTE_MASK) {
- case SFF_8024_ID_QSFP:
- eeprom->type = MLX5E_ETH_MODULE_SFF_8436;
- eeprom->len = MLX5E_ETH_MODULE_SFF_8436_LEN;
- break;
- case SFF_8024_ID_QSFPPLUS:
- case SFF_8024_ID_QSFP28:
- if ((data & MLX5_EEPROM_IDENTIFIER_BYTE_MASK) == SFF_8024_ID_QSFP28 ||
- ((data & MLX5_EEPROM_REVISION_ID_BYTE_MASK) >> 8) >= 0x3) {
- eeprom->type = MLX5E_ETH_MODULE_SFF_8636;
- eeprom->len = MLX5E_ETH_MODULE_SFF_8636_LEN;
- } else {
- eeprom->type = MLX5E_ETH_MODULE_SFF_8436;
- eeprom->len = MLX5E_ETH_MODULE_SFF_8436_LEN;
- }
- if ((data & MLX5_EEPROM_PAGE_3_VALID_BIT_MASK) == 0)
- eeprom->page_valid = 1;
- break;
- case SFF_8024_ID_SFP:
- eeprom->type = MLX5E_ETH_MODULE_SFF_8472;
- eeprom->len = MLX5E_ETH_MODULE_SFF_8472_LEN;
- break;
- default:
- mlx5_en_err(priv->ifp,
- "Not recognized cable type = 0x%x(%s)\n",
- data & MLX5_EEPROM_IDENTIFIER_BYTE_MASK,
- sff_8024_id[data & MLX5_EEPROM_IDENTIFIER_BYTE_MASK]);
- return (EINVAL);
- }
- return (0);
-}
-
-/* Read both low and high pages of the eeprom */
-static int
-mlx5e_get_eeprom(struct mlx5e_priv *priv, struct mlx5e_eeprom *ee)
-{
- struct mlx5_core_dev *dev = priv->mdev;
- int size_read = 0;
- int ret;
-
- if (ee->len == 0)
- return (EINVAL);
-
- /* Read low page of the eeprom */
- while (ee->device_addr < ee->len) {
- ret = mlx5_query_eeprom(dev, ee->i2c_addr, ee->page_num, ee->device_addr,
- ee->len - ee->device_addr, ee->module_num,
- ee->data + (ee->device_addr / 4), &size_read);
- if (ret) {
- mlx5_en_err(priv->ifp,
- "Failed reading eeprom, error = 0x%02x\n",ret);
- return (ret);
- }
- ee->device_addr += size_read;
- }
-
- /* Read high page of the eeprom */
- if (ee->page_valid) {
- ee->device_addr = MLX5E_EEPROM_HIGH_PAGE_OFFSET;
- ee->page_num = MLX5E_EEPROM_HIGH_PAGE;
- size_read = 0;
- while (ee->device_addr < MLX5E_EEPROM_PAGE_LENGTH) {
- ret = mlx5_query_eeprom(dev, ee->i2c_addr, ee->page_num,
- ee->device_addr, MLX5E_EEPROM_PAGE_LENGTH - ee->device_addr,
- ee->module_num, ee->data + (ee->len / 4) +
- ((ee->device_addr - MLX5E_EEPROM_HIGH_PAGE_OFFSET) / 4),
- &size_read);
- if (ret) {
- mlx5_en_err(priv->ifp,
- "Failed reading eeprom, error = 0x%02x\n",
- ret);
- return (ret);
- }
- ee->device_addr += size_read;
- }
- }
- return (0);
-}
-
-static void
-mlx5e_print_eeprom(struct mlx5e_eeprom *eeprom)
-{
- int row;
- int index_in_row;
- int byte_to_write = 0;
- int line_length = 16;
-
- printf("\nOffset\t\tValues\n");
- printf("------\t\t------");
- while (byte_to_write < eeprom->len) {
- printf("\n0x%04X\t\t", byte_to_write);
- for (index_in_row = 0; index_in_row < line_length; index_in_row++) {
- printf("%02X ", ((u8 *)eeprom->data)[byte_to_write]);
- byte_to_write++;
- }
- }
-
- if (eeprom->page_valid) {
- row = MLX5E_EEPROM_HIGH_PAGE_OFFSET;
- printf("\n\nUpper Page 0x03\n");
- printf("\nOffset\t\tValues\n");
- printf("------\t\t------");
- while (row < MLX5E_EEPROM_PAGE_LENGTH) {
- printf("\n0x%04X\t\t", row);
- for (index_in_row = 0; index_in_row < line_length; index_in_row++) {
- printf("%02X ", ((u8 *)eeprom->data)[byte_to_write]);
- byte_to_write++;
- row++;
- }
- }
- }
-}
-
-/*
- * Read cable EEPROM module information by first inspecting the first
- * three bytes to get the initial information for a whole reading.
- * Information will be printed to dmesg.
- */
-static int
-mlx5e_read_eeprom(SYSCTL_HANDLER_ARGS)
-{
- struct mlx5e_priv *priv = arg1;
- struct mlx5e_eeprom eeprom;
- int error;
- int result = 0;
-
- PRIV_LOCK(priv);
- error = sysctl_handle_int(oidp, &result, 0, req);
- if (error || !req->newptr)
- goto done;
-
- /* Check if device is gone */
- if (priv->gone) {
- error = ENXIO;
- goto done;
- }
-
- if (result == 1) {
- eeprom.i2c_addr = MLX5E_I2C_ADDR_LOW;
- eeprom.device_addr = 0;
- eeprom.page_num = MLX5E_EEPROM_LOW_PAGE;
- eeprom.page_valid = 0;
-
- /* Read three first bytes to get important info */
- error = mlx5e_get_eeprom_info(priv, &eeprom);
- if (error) {
- mlx5_en_err(priv->ifp,
- "Failed reading eeprom's initial information\n");
- error = 0;
- goto done;
- }
- /*
- * Allocate needed length buffer and additional space for
- * page 0x03
- */
- eeprom.data = malloc(eeprom.len + MLX5E_EEPROM_PAGE_LENGTH,
- M_MLX5EN, M_WAITOK | M_ZERO);
-
- /* Read the whole eeprom information */
- error = mlx5e_get_eeprom(priv, &eeprom);
- if (error) {
- mlx5_en_err(priv->ifp, "Failed reading eeprom\n");
- error = 0;
- /*
- * Continue printing partial information in case of
- * an error
- */
- }
- mlx5e_print_eeprom(&eeprom);
- free(eeprom.data, M_MLX5EN);
- }
-done:
- PRIV_UNLOCK(priv);
- return (error);
-}
-
static const char *mlx5e_params_desc[] = {
MLX5E_PARAMS(MLX5E_STATS_DESC)
};
@@ -1347,11 +1139,6 @@ mlx5e_create_ethtool(struct mlx5e_priv *priv)
__DECONST(void *, pnameunit), 0,
"PCI device name");
- /* EEPROM support */
- SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(node), OID_AUTO, "eeprom_info",
- CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, priv, 0,
- mlx5e_read_eeprom, "I", "EEPROM information");
-
/* Diagnostics support */
mlx5e_create_diagnostics(priv);
diff --git a/sys/dev/mlx5/mlx5_en/mlx5_en_main.c b/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
index b0bf78a47cdd..b346c78fe399 100644
--- a/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
+++ b/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
@@ -3397,9 +3397,9 @@ out:
* The internal conversion is as follows:
*/
if (i2c.dev_addr == 0xA0)
- read_addr = MLX5E_I2C_ADDR_LOW;
+ read_addr = MLX5_I2C_ADDR_LOW;
else if (i2c.dev_addr == 0xA2)
- read_addr = MLX5E_I2C_ADDR_HIGH;
+ read_addr = MLX5_I2C_ADDR_HIGH;
else {
mlx5_en_err(ifp,
"Query eeprom failed, Invalid Address: %X\n",
@@ -3408,7 +3408,7 @@ out:
goto err_i2c;
}
error = mlx5_query_eeprom(priv->mdev,
- read_addr, MLX5E_EEPROM_LOW_PAGE,
+ read_addr, MLX5_EEPROM_LOW_PAGE,
(uint32_t)i2c.offset, (uint32_t)i2c.len, module_num,
(uint32_t *)i2c.data, &size_read);
if (error) {
@@ -3420,7 +3420,7 @@ out:
if (i2c.len > MLX5_EEPROM_MAX_BYTES) {
error = mlx5_query_eeprom(priv->mdev,
- read_addr, MLX5E_EEPROM_LOW_PAGE,
+ read_addr, MLX5_EEPROM_LOW_PAGE,
(uint32_t)(i2c.offset + size_read),
(uint32_t)(i2c.len - size_read), module_num,
(uint32_t *)(i2c.data + size_read), &size_read);
diff --git a/sys/dev/mlx5/mlx5io.h b/sys/dev/mlx5/mlx5io.h
index 721241307c98..4e88ccd10681 100644
--- a/sys/dev/mlx5/mlx5io.h
+++ b/sys/dev/mlx5/mlx5io.h
@@ -55,11 +55,19 @@ struct mlx5_fw_update {
size_t img_fw_data_len;
};
+struct mlx5_eeprom_get {
+ struct mlx5_tool_addr devaddr;
+ uint32_t *eeprom_info_buf;
+ uint8_t eeprom_info_page_valid;
+ size_t eeprom_info_out_len;
+};
+
#define MLX5_FWDUMP_GET _IOWR('m', 1, struct mlx5_fwdump_get)
#define MLX5_FWDUMP_RESET _IOW('m', 2, struct mlx5_tool_addr)
#define MLX5_FWDUMP_FORCE _IOW('m', 3, struct mlx5_tool_addr)
#define MLX5_FW_UPDATE _IOW('m', 4, struct mlx5_fw_update)
#define MLX5_FW_RESET _IOW('m', 5, struct mlx5_tool_addr)
+#define MLX5_EEPROM_GET _IOWR('m', 6, struct mlx5_eeprom_get)
#ifndef _KERNEL
#define MLX5_DEV_PATH _PATH_DEV"mlx5ctl"
diff --git a/sys/dev/mlx5/port.h b/sys/dev/mlx5/port.h
index 36cb01160781..043c70388301 100644
--- a/sys/dev/mlx5/port.h
+++ b/sys/dev/mlx5/port.h
@@ -50,13 +50,34 @@ enum mlx5_an_status {
MLX5_AN_LINK_DOWN = 4,
};
+/* EEPROM I2C Addresses */
+#define MLX5_I2C_ADDR_LOW 0x50
+#define MLX5_I2C_ADDR_HIGH 0x51
+#define MLX5_EEPROM_PAGE_LENGTH 256
#define MLX5_EEPROM_MAX_BYTES 32
#define MLX5_EEPROM_IDENTIFIER_BYTE_MASK 0x000000ff
#define MLX5_EEPROM_REVISION_ID_BYTE_MASK 0x0000ff00
#define MLX5_EEPROM_PAGE_3_VALID_BIT_MASK 0x00040000
-#define MLX5_I2C_ADDR_LOW 0x50
-#define MLX5_I2C_ADDR_HIGH 0x51
-#define MLX5_EEPROM_PAGE_LENGTH 256
+#define MLX5_EEPROM_LOW_PAGE 0x0
+#define MLX5_EEPROM_HIGH_PAGE 0x3
+#define MLX5_EEPROM_HIGH_PAGE_OFFSET 128
+#define MLX5_EEPROM_INFO_BYTES 0x3
+
+/* EEPROM Standards for plug in modules */
+#ifndef MLX5_ETH_MODULE_SFF_8472
+#define MLX5_ETH_MODULE_SFF_8472 0x1
+#define MLX5_ETH_MODULE_SFF_8472_LEN 128
+#endif
+
+#ifndef MLX5_ETH_MODULE_SFF_8636
+#define MLX5_ETH_MODULE_SFF_8636 0x2
+#define MLX5_ETH_MODULE_SFF_8636_LEN 256
+#endif
+
+#ifndef MLX5_ETH_MODULE_SFF_8436
+#define MLX5_ETH_MODULE_SFF_8436 0x3
+#define MLX5_ETH_MODULE_SFF_8436_LEN 256
+#endif
enum mlx5e_link_speed {
MLX5E_1000BASE_CX_SGMII = 0,