From 76f23fe9d13d5e7ff73329d706034312b15fa5c4 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 18 Mar 2026 13:32:42 -0700 Subject: [PATCH] cndm: Add support for reading hardware IDs Signed-off-by: Alex Forencich --- src/cndm/modules/cndm/cndm.h | 7 ++++ src/cndm/modules/cndm/cndm_cmd.c | 61 ++++++++++++++++++++++++++++ src/cndm/modules/cndm/cndm_devlink.c | 6 +++ src/cndm/modules/cndm/cndm_hw.h | 51 +++++++++++++++++++++++ src/cndm/modules/cndm/cndm_main.c | 21 ++++++++++ 5 files changed, 146 insertions(+) diff --git a/src/cndm/modules/cndm/cndm.h b/src/cndm/modules/cndm/cndm.h index ab02471..f0b22a5 100644 --- a/src/cndm/modules/cndm/cndm.h +++ b/src/cndm/modules/cndm/cndm.h @@ -97,6 +97,11 @@ struct cndm_dev { u8 log_max_rq_sz; u8 rq_pool; u8 rqe_ver; + + // HW IDs + char sn_str[32]; + char base_mac[ETH_ALEN]; + int mac_cnt; }; struct cndm_tx_info { @@ -237,6 +242,8 @@ struct cndm_priv { int cndm_exec_mbox_cmd(struct cndm_dev *cdev, void *cmd, void *rsp); int cndm_exec_cmd(struct cndm_dev *cdev, void *cmd, void *rsp); int cndm_access_reg(struct cndm_dev *cdev, u32 reg, int raw, int write, u64 *data); +int cndm_hwid_sn_rd(struct cndm_dev *cdev, int *len, void *data); +int cndm_hwid_mac_rd(struct cndm_dev *cdev, u16 index, int *cnt, void *data); // cndm_devlink.c struct devlink *cndm_devlink_alloc(struct device *dev); diff --git a/src/cndm/modules/cndm/cndm_cmd.c b/src/cndm/modules/cndm/cndm_cmd.c index 28d935e..ad5f44f 100644 --- a/src/cndm/modules/cndm/cndm_cmd.c +++ b/src/cndm/modules/cndm/cndm_cmd.c @@ -91,3 +91,64 @@ int cndm_access_reg(struct cndm_dev *cdev, u32 reg, int raw, int write, u64 *dat return 0; } + +int cndm_hwid_sn_rd(struct cndm_dev *cdev, int *len, void *data) +{ + struct cndm_cmd_hwid cmd; + struct cndm_cmd_hwid rsp; + int ret = 0; + char buf[64]; + char *ptr; + + cmd.opcode = CNDM_CMD_OP_HWID; + cmd.flags = 0x00000000; + cmd.index = 0; + cmd.brd_opcode = CNDM_CMD_BRD_OP_HWID_SN_RD; + cmd.brd_flags = 0x00000000; + + ret = cndm_exec_cmd(cdev, &cmd, &rsp); + if (ret) + return ret; + + if (rsp.status || rsp.brd_status) + return rsp.status ? rsp.status : rsp.brd_status; + + // memcpy(&buf, ((void *)&rsp.data), min(cmd.len, 32)); // TODO + memcpy(&buf, ((void *)&rsp.data), 32); + buf[32] = 0; + ptr = strim(buf); + + if (len) + *len = strlen(ptr); + if (data) + strscpy(data, ptr, 32); + + return 0; +} + +int cndm_hwid_mac_rd(struct cndm_dev *cdev, u16 index, int *cnt, void *data) +{ + struct cndm_cmd_hwid cmd; + struct cndm_cmd_hwid rsp; + int ret = 0; + + cmd.opcode = CNDM_CMD_OP_HWID; + cmd.flags = 0x00000000; + cmd.index = index; + cmd.brd_opcode = CNDM_CMD_BRD_OP_HWID_MAC_RD; + cmd.brd_flags = 0x00000000; + + ret = cndm_exec_cmd(cdev, &cmd, &rsp); + if (ret) + return ret; + + if (rsp.status || rsp.brd_status) + return rsp.status ? rsp.status : rsp.brd_status; + + if (cnt) + *cnt = 1; // *((u16 *)&rsp.data); // TODO + if (data) + memcpy(data, ((void *)&rsp.data)+2, ETH_ALEN); + + return 0; +} diff --git a/src/cndm/modules/cndm/cndm_devlink.c b/src/cndm/modules/cndm/cndm_devlink.c index 2d1a1f6..5d20bc4 100644 --- a/src/cndm/modules/cndm/cndm_devlink.c +++ b/src/cndm/modules/cndm/cndm_devlink.c @@ -44,6 +44,12 @@ static int cndm_devlink_info_get(struct devlink *devlink, if (ret) return ret; + if (strlen(cdev->sn_str) != 0) { + ret = devlink_info_board_serial_number_put(req, cdev->sn_str); + if (ret) + return ret; + } + snprintf(str, sizeof(str), "%08x", cdev->fw_id); ret = devlink_info_version_running_put(req, "fw.id", str); diff --git a/src/cndm/modules/cndm/cndm_hw.h b/src/cndm/modules/cndm/cndm_hw.h index 2ffc012..e484fb5 100644 --- a/src/cndm/modules/cndm/cndm_hw.h +++ b/src/cndm/modules/cndm/cndm_hw.h @@ -19,6 +19,9 @@ Authors: #define CNDM_CMD_OP_ACCESS_REG 0x0180 #define CNDM_CMD_OP_PTP 0x0190 +#define CNDM_CMD_OP_HWID 0x01A0 +#define CNDM_CMD_OP_HWMON 0x01B0 +#define CNDM_CMD_OP_PLL 0x01C0 #define CNDM_CMD_OP_CREATE_EQ 0x0200 #define CNDM_CMD_OP_MODIFY_EQ 0x0201 @@ -45,6 +48,31 @@ Authors: #define CNDM_CMD_OP_QUERY_QP 0x0242 #define CNDM_CMD_OP_DESTROY_QP 0x0243 +#define CNDM_CMD_BRD_OP_NOP 0x0000 + +#define CNDM_CMD_BRD_OP_FLASH_RD 0x0100 +#define CNDM_CMD_BRD_OP_FLASH_WR 0x0101 +#define CNDM_CMD_BRD_OP_FLASH_CMD 0x0108 + +#define CNDM_CMD_BRD_OP_EEPROM_RD 0x0200 +#define CNDM_CMD_BRD_OP_EEPROM_WR 0x0201 + +#define CNDM_CMD_BRD_OP_OPTIC_RD 0x0300 +#define CNDM_CMD_BRD_OP_OPTIC_WR 0x0301 + +#define CNDM_CMD_BRD_OP_HWID_SN_RD 0x0400 +#define CNDM_CMD_BRD_OP_HWID_VPD_RD 0x0410 +#define CNDM_CMD_BRD_OP_HWID_MAC_RD 0x0480 + +#define CNDM_CMD_BRD_OP_PLL_STATUS_RD 0x0500 +#define CNDM_CMD_BRD_OP_PLL_TUNE_RAW_RD 0x0502 +#define CNDM_CMD_BRD_OP_PLL_TUNE_RAW_WR 0x0503 +#define CNDM_CMD_BRD_OP_PLL_TUNE_PPT_RD 0x0504 +#define CNDM_CMD_BRD_OP_PLL_TUNE_PPT_WR 0x0505 + +#define CNDM_CMD_BRD_OP_I2C_RD 0x8100 +#define CNDM_CMD_BRD_OP_I2C_WR 0x8101 + struct cndm_cmd_cfg { __le16 rsvd; union { @@ -153,6 +181,29 @@ struct cndm_cmd_ptp { __le32 rsvd2[2]; }; +struct cndm_cmd_hwid { + __le16 rsvd; + union { + __le16 opcode; + __le16 status; + }; + __le32 flags; + __le16 index; + union { + __le16 brd_opcode; + __le16 brd_status; + }; + __le32 brd_flags; + __u8 page; + __u8 bank; + __u8 dev_addr_offset; + __u8 rsvd2; + __le32 addr; + __le32 len; + __le32 rsvd3; + __le32 data[8]; +}; + struct cndm_cmd_queue { __le16 rsvd; union { diff --git a/src/cndm/modules/cndm/cndm_main.c b/src/cndm/modules/cndm/cndm_main.c index f4b2065..a034d0d 100644 --- a/src/cndm/modules/cndm/cndm_main.c +++ b/src/cndm/modules/cndm/cndm_main.c @@ -209,6 +209,27 @@ static int cndm_common_probe(struct cndm_dev *cdev) dev_info(dev, "RQ pool: %d", cdev->rq_pool); dev_info(dev, "RQE version: %d", cdev->rqe_ver); + dev_info(dev, "Read HW IDs"); + + ret = cndm_hwid_sn_rd(cdev, NULL, &cdev->sn_str); + if (ret) { + dev_info(dev, "No readable serial number"); + } else { + dev_info(dev, "SN: %s", cdev->sn_str); + } + + ret = cndm_hwid_mac_rd(cdev, 0, &cdev->mac_cnt, &cdev->base_mac); + if (ret) { + dev_info(dev, "No readable MACs"); + cdev->mac_cnt = 0; + } else if (!is_valid_ether_addr(cdev->base_mac)) { + dev_warn(dev, "Base MAC is invalid"); + cdev->mac_cnt = 0; + } else { + dev_info(dev, "MAC count: %d", cdev->mac_cnt); + dev_info(dev, "Base MAC: %pM", cdev->base_mac); + } + if (cdev->port_count > ARRAY_SIZE(cdev->ndev)) cdev->port_count = ARRAY_SIZE(cdev->ndev);