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