provide ptypes、fw_version、module info/eeprom ops.
Signed-off-by: Junlong Wang <wang.junlong1@zte.com.cn>
---
drivers/net/zxdh/zxdh_ethdev.c | 30 +++++
drivers/net/zxdh/zxdh_ethdev_ops.c | 200 +++++++++++++++++++++++++++++
drivers/net/zxdh/zxdh_ethdev_ops.h | 5 +
drivers/net/zxdh/zxdh_msg.h | 37 +++++-
4 files changed, 271 insertions(+), 1 deletion(-)
diff --git a/drivers/net/zxdh/zxdh_ethdev.c b/drivers/net/zxdh/zxdh_ethdev.c
index 3bdbc2fe6d..5546b6bfc3 100644
--- a/drivers/net/zxdh/zxdh_ethdev.c
+++ b/drivers/net/zxdh/zxdh_ethdev.c
@@ -1343,6 +1343,32 @@ zxdh_txq_info_get(struct rte_eth_dev *dev, uint16_t tx_queue_id, struct rte_eth_
qinfo->queue_state = dev->data->tx_queue_state[tx_queue_id];
}
+static const uint32_t *
+zxdh_dev_supported_ptypes_get(struct rte_eth_dev *dev, size_t *ptype_sz)
+{
+ static const uint32_t ptypes[] = {
+ RTE_PTYPE_L2_ETHER,
+ RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
+ RTE_PTYPE_L3_IPV6_EXT_UNKNOWN,
+ RTE_PTYPE_L4_NONFRAG,
+ RTE_PTYPE_L4_FRAG,
+ RTE_PTYPE_L4_TCP,
+ RTE_PTYPE_L4_UDP,
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN,
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN,
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ RTE_PTYPE_INNER_L4_FRAG,
+ RTE_PTYPE_INNER_L4_TCP,
+ RTE_PTYPE_INNER_L4_UDP,
+ RTE_PTYPE_UNKNOWN
+ };
+
+ if (!dev->rx_pkt_burst)
+ return NULL;
+ *ptype_sz = sizeof(ptypes);
+ return ptypes;
+}
+
/* dev_ops for zxdh, bare necessities for basic operation */
static const struct eth_dev_ops zxdh_eth_dev_ops = {
.dev_configure = zxdh_dev_configure,
@@ -1378,6 +1404,10 @@ static const struct eth_dev_ops zxdh_eth_dev_ops = {
.xstats_get_names = zxdh_dev_xstats_get_names,
.xstats_reset = zxdh_dev_stats_reset,
.mtu_set = zxdh_dev_mtu_set,
+ .fw_version_get = zxdh_dev_fw_version_get,
+ .get_module_info = zxdh_dev_get_module_info,
+ .get_module_eeprom = zxdh_dev_get_module_eeprom,
+ .dev_supported_ptypes_get = zxdh_dev_supported_ptypes_get,
};
static int32_t
diff --git a/drivers/net/zxdh/zxdh_ethdev_ops.c b/drivers/net/zxdh/zxdh_ethdev_ops.c
index 74cf058957..3e88860765 100644
--- a/drivers/net/zxdh/zxdh_ethdev_ops.c
+++ b/drivers/net/zxdh/zxdh_ethdev_ops.c
@@ -2023,3 +2023,203 @@ zxdh_dev_xstats_get_names(struct rte_eth_dev *dev,
}
return nstats;
}
+
+int
+zxdh_dev_fw_version_get(struct rte_eth_dev *dev,
+ char *fw_version, size_t fw_size __rte_unused)
+{
+ struct zxdh_hw *hw = dev->data->dev_private;
+ struct zxdh_msg_info msg_info = {0};
+ struct zxdh_msg_reply_info reply_info = {0};
+ char fw_ver[ZXDH_FWVERS_LEN] = {0};
+ uint32_t ret = 0;
+
+ zxdh_agent_msg_build(hw, ZXDH_FLASH_FIR_VERSION_GET, &msg_info);
+
+ struct zxdh_msg_recviver_mem rsp_data = {
+ .recv_buffer = (void *)&reply_info,
+ .buffer_len = sizeof(struct zxdh_msg_reply_info),
+ };
+
+ ret = zxdh_send_msg_to_riscv(dev, &msg_info, sizeof(struct zxdh_msg_info),
+ &reply_info, sizeof(struct zxdh_msg_reply_info),
+ ZXDH_MODULE_FLASH);
+ if (ret) {
+ PMD_DRV_LOG(ERR, "Failed to send msg: port 0x%x msg type %d",
+ hw->vport.vport, ZXDH_FLASH_FIR_VERSION_GET);
+ return -1;
+ }
+ struct zxdh_msg_reply_body *ack_msg =
+ &(((struct zxdh_msg_reply_info *)rsp_data.recv_buffer)->reply_body);
+
+ memcpy(fw_ver, ack_msg->flash_msg.firmware_version, ZXDH_FWVERS_LEN);
+ snprintf(fw_version, ZXDH_FWVERS_LEN - 1, "%s", fw_ver);
+
+ return 0;
+}
+
+static uint8_t
+zxdh_en_module_eeprom_read(struct rte_eth_dev *dev,
+ struct zxdh_mac_module_eeprom_msg *query, uint8_t *data)
+{
+ struct zxdh_hw *hw = dev->data->dev_private;
+ struct zxdh_msg_info msg_info = {0};
+ struct zxdh_msg_reply_info reply_info = {0};
+ uint8_t ret = 0;
+
+ zxdh_agent_msg_build(hw, ZXDH_MAC_MODULE_EEPROM_READ, &msg_info);
+
+ msg_info.data.module_eeprom_msg.i2c_addr = query->i2c_addr;
+ msg_info.data.module_eeprom_msg.bank = query->bank;
+ msg_info.data.module_eeprom_msg.page = query->page;
+ msg_info.data.module_eeprom_msg.offset = query->offset;
+ msg_info.data.module_eeprom_msg.length = query->length;
+
+ struct zxdh_msg_recviver_mem rsp_data = {
+ .recv_buffer = (void *)&reply_info,
+ .buffer_len = sizeof(struct zxdh_msg_reply_info),
+ };
+
+ ret = zxdh_send_msg_to_riscv(dev, &msg_info, sizeof(struct zxdh_msg_info),
+ &reply_info, sizeof(struct zxdh_msg_reply_info),
+ ZXDH_BAR_MODULE_MAC);
+ if (ret) {
+ PMD_DRV_LOG(ERR, "Failed to send msg: port 0x%x msg type %d",
+ hw->vport.vport, ZXDH_MAC_MODULE_EEPROM_READ);
+ return -1;
+ }
+ struct zxdh_msg_reply_body *ack_msg =
+ &(((struct zxdh_msg_reply_info *)rsp_data.recv_buffer)->reply_body);
+
+ if (data)
+ memcpy(data, ack_msg->module_eeprom_msg.data, ack_msg->module_eeprom_msg.length);
+
+ return ack_msg->module_eeprom_msg.length;
+}
+
+int
+zxdh_dev_get_module_info(struct rte_eth_dev *dev,
+ struct rte_eth_dev_module_info *modinfo)
+{
+ struct zxdh_hw *hw = dev->data->dev_private;
+ struct zxdh_mac_module_eeprom_msg query = {0};
+ uint8_t read_bytes;
+ uint8_t data[2] = {0};
+
+ if (!hw->is_pf)
+ return -EOPNOTSUPP;
+
+ query.i2c_addr = ZXDH_SFF_I2C_ADDRESS_LOW;
+ query.page = 0;
+ query.offset = 0;
+ query.length = 2;
+
+ read_bytes = zxdh_en_module_eeprom_read(dev, &query, data);
+ if (read_bytes != query.length) {
+ PMD_DRV_LOG(ERR, "zxdh_en_module_eeprom_read failed!");
+ return -EIO;
+ }
+
+ switch (data[0]) {
+ case ZXDH_MODULE_ID_SFP:
+ modinfo->type = RTE_ETH_MODULE_SFF_8472;
+ modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8472_LEN;
+ break;
+ case ZXDH_MODULE_ID_QSFP:
+ modinfo->type = RTE_ETH_MODULE_SFF_8436;
+ modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8436_MAX_LEN;
+ break;
+ case ZXDH_MODULE_ID_QSFP_PLUS:
+ case ZXDH_MODULE_ID_QSFP28:
+ if (data[1] < 3) {
+ modinfo->type = RTE_ETH_MODULE_SFF_8436;
+ modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8436_MAX_LEN;
+ } else {
+ modinfo->type = RTE_ETH_MODULE_SFF_8636;
+ modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8636_MAX_LEN;
+ }
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "can not recognize module identifier 0x%x!", data[0]);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+
+int
+zxdh_dev_get_module_eeprom(struct rte_eth_dev *dev, struct rte_dev_eeprom_info *info)
+{
+ struct zxdh_mac_module_eeprom_msg query = {0};
+ uint32_t offset = info->offset;
+ uint32_t length = info->length;
+ uint32_t offset_boundary = 0;
+ uint32_t total_read_bytes = 0;
+ uint8_t read_bytes = 0;
+ uint8_t identifier;
+ uint8_t *data = NULL;
+
+ if (!info->length)
+ return -EINVAL;
+
+ data = info->data;
+ memset(data, 0, info->length);
+
+ query.i2c_addr = ZXDH_SFF_I2C_ADDRESS_LOW;
+ query.bank = 0;
+ query.page = 0;
+ query.offset = 0;
+ query.length = 1;
+ read_bytes = zxdh_en_module_eeprom_read(dev, &query, &identifier);
+ if (read_bytes != query.length) {
+ PMD_DRV_LOG(ERR, "read eeprom failed(read_bytes %d != query.length %d)!",
+ read_bytes, query.length);
+ return -EIO;
+ }
+
+ while (total_read_bytes < info->length) {
+ if (identifier == ZXDH_MODULE_ID_SFP) {
+ if (offset < 256) {
+ query.i2c_addr = ZXDH_SFF_I2C_ADDRESS_LOW;
+ query.page = 0;
+ query.offset = offset;
+ } else {
+ query.i2c_addr = ZXDH_SFF_I2C_ADDRESS_HIGH;
+ query.page = 0;
+ query.offset = offset - 256;
+ }
+ offset_boundary = (query.offset < 128) ? 128 : 256;
+ query.length = ((query.offset + length) > offset_boundary) ?
+ (offset_boundary - query.offset) : length;
+ } else if (identifier == ZXDH_MODULE_ID_QSFP ||
+ identifier == ZXDH_MODULE_ID_QSFP_PLUS ||
+ identifier == ZXDH_MODULE_ID_QSFP28) {
+ query.i2c_addr = ZXDH_SFF_I2C_ADDRESS_LOW;
+ if (offset < 256) {
+ query.page = 0;
+ query.offset = offset;
+ } else {
+ query.page = (offset - 256) / 128 + 1;
+ query.offset = offset - 128 * query.page;
+ }
+ offset_boundary = (query.offset < 128) ? 128 : 256;
+ query.length = ((query.offset + length) > offset_boundary) ?
+ (offset_boundary - query.offset) : length;
+ } else {
+ PMD_DRV_LOG(ERR, "can not recognize module identifier 0x%x!", identifier);
+ return -EINVAL;
+ }
+
+ read_bytes = zxdh_en_module_eeprom_read(dev, &query, data + total_read_bytes);
+ if (read_bytes != query.length) {
+ PMD_DRV_LOG(ERR, "read eeprom failed(read_bytes %d != query.length %d)",
+ read_bytes, query.length);
+ return -EIO;
+ }
+ total_read_bytes = (total_read_bytes + read_bytes) % UINT32_MAX;
+ offset += read_bytes;
+ length -= read_bytes;
+ }
+ return 0;
+}
diff --git a/drivers/net/zxdh/zxdh_ethdev_ops.h b/drivers/net/zxdh/zxdh_ethdev_ops.h
index 37d0299f23..08b9e3341b 100644
--- a/drivers/net/zxdh/zxdh_ethdev_ops.h
+++ b/drivers/net/zxdh/zxdh_ethdev_ops.h
@@ -103,5 +103,10 @@ int32_t zxdh_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstat
int32_t zxdh_dev_xstats_get_names(struct rte_eth_dev *dev,
struct rte_eth_xstat_name *xstats_names,
__rte_unused unsigned int limit);
+int zxdh_dev_fw_version_get(struct rte_eth_dev *dev, char *fw_version,
+ size_t fw_size __rte_unused);
+int zxdh_dev_get_module_info(struct rte_eth_dev *dev,
+ struct rte_eth_dev_module_info *modinfo);
+int zxdh_dev_get_module_eeprom(struct rte_eth_dev *dev, struct rte_dev_eeprom_info *info);
#endif /* ZXDH_ETHDEV_OPS_H */
diff --git a/drivers/net/zxdh/zxdh_msg.h b/drivers/net/zxdh/zxdh_msg.h
index cb830fa2da..b3e202c026 100644
--- a/drivers/net/zxdh/zxdh_msg.h
+++ b/drivers/net/zxdh/zxdh_msg.h
@@ -48,10 +48,17 @@
#define ZXDH_MSG_REPLY_BODY_MAX_LEN \
(ZXDH_MSG_PAYLOAD_MAX_LEN - sizeof(struct zxdh_msg_reply_head))
-#define ZXDH_MSG_HEAD_LEN 8
+#define ZXDH_MSG_HEAD_LEN 8
#define ZXDH_MSG_REQ_BODY_MAX_LEN \
(ZXDH_MSG_PAYLOAD_MAX_LEN - ZXDH_MSG_HEAD_LEN)
+#define ZXDH_FWVERS_LEN 32
+
+#define ZXDH_SFF_I2C_ADDRESS_LOW (0x50)
+#define ZXDH_SFF_I2C_ADDRESS_HIGH (0x51)
+
+#define ZXDH_MODULE_EEPROM_DATA_LEN 128
+
#define ZXDH_MAC_FILTER 0xaa
#define ZXDH_MAC_UNFILTER 0xff
#define ZXDH_PROMISC_MODE 1
@@ -180,13 +187,25 @@ enum pciebar_layout_type {
ZXDH_URI_MAX,
};
+enum zxdh_module_id {
+ ZXDH_MODULE_ID_SFP = 0x3,
+ ZXDH_MODULE_ID_QSFP = 0xC,
+ ZXDH_MODULE_ID_QSFP_PLUS = 0xD,
+ ZXDH_MODULE_ID_QSFP28 = 0x11,
+ ZXDH_MODULE_ID_QSFP_DD = 0x18,
+ ZXDH_MODULE_ID_OSFP = 0x19,
+ ZXDH_MODULE_ID_DSFP = 0x1B,
+};
+
/* riscv msg opcodes */
enum zxdh_agent_msg_type {
ZXDH_MAC_STATS_GET = 10,
ZXDH_MAC_STATS_RESET,
ZXDH_MAC_LINK_GET = 14,
+ ZXDH_MAC_MODULE_EEPROM_READ = 20,
ZXDH_VQM_DEV_STATS_GET = 21,
ZXDH_VQM_DEV_STATS_RESET,
+ ZXDH_FLASH_FIR_VERSION_GET = 23,
ZXDH_VQM_QUEUE_STATS_GET = 24,
ZXDH_VQM_QUEUE_STATS_RESET,
};
@@ -320,6 +339,19 @@ enum zxdh_reps_flag {
ZXDH_REPS_INVALID = 0xee,
};
+struct __rte_packed_begin zxdh_mac_module_eeprom_msg {
+ uint8_t i2c_addr;
+ uint8_t bank;
+ uint8_t page;
+ uint8_t offset;
+ uint8_t length;
+ uint8_t data[ZXDH_MODULE_EEPROM_DATA_LEN];
+} __rte_packed_end;
+
+struct zxdh_flash_msg {
+ uint8_t firmware_version[ZXDH_FWVERS_LEN];
+};
+
struct zxdh_np_stats_updata_msg {
uint32_t clear_mode;
};
@@ -352,6 +384,8 @@ struct __rte_packed_begin zxdh_msg_reply_body {
struct zxdh_rss_hf rss_hf;
struct zxdh_hw_vqm_stats vqm_stats;
struct zxdh_np_stats_updata_msg np_stats_query;
+ struct zxdh_flash_msg flash_msg;
+ struct zxdh_mac_module_eeprom_msg module_eeprom_msg;
} __rte_packed_end;
} __rte_packed_end;
@@ -438,6 +472,7 @@ struct __rte_packed_begin zxdh_msg_info {
struct zxdh_rss_enable rss_enable;
struct zxdh_rss_hf rss_hf;
struct zxdh_np_stats_updata_msg np_stats_query;
+ struct zxdh_mac_module_eeprom_msg module_eeprom_msg;
} __rte_packed_end data;
} __rte_packed_end;
--
2.27.0