cndm: Add support for reading hardware IDs

Signed-off-by: Alex Forencich <alex@alexforencich.com>
This commit is contained in:
Alex Forencich
2026-03-18 13:32:42 -07:00
parent 378f1d34ec
commit 76f23fe9d1
5 changed files with 146 additions and 0 deletions

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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 {

View File

@@ -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);