provide ptypes、fw_version、module info/eeprom ops. Signed-off-by: Junlong Wang --- 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