provide ptypes、FW version、EEPROM ops.

Signed-off-by: Junlong Wang <wang.junlo...@zte.com.cn>
---
 doc/guides/nics/features/zxdh.ini  |   2 +
 drivers/net/zxdh/zxdh_ethdev.c     |  30 +++++
 drivers/net/zxdh/zxdh_ethdev_ops.c | 200 +++++++++++++++++++++++++++++
 drivers/net/zxdh/zxdh_ethdev_ops.h |   3 +
 drivers/net/zxdh/zxdh_msg.h        |  38 +++++-
 5 files changed, 272 insertions(+), 1 deletion(-)

diff --git a/doc/guides/nics/features/zxdh.ini 
b/doc/guides/nics/features/zxdh.ini
index cad756ac6e..55da709e53 100644
--- a/doc/guides/nics/features/zxdh.ini
+++ b/doc/guides/nics/features/zxdh.ini
@@ -31,3 +31,5 @@ Inner L4 checksum    = Y
 LRO                  = Y
 TSO                  = Y
 Extended stats       = Y
+FW version           = Y
+Module EEPROM dump   = Y
diff --git a/drivers/net/zxdh/zxdh_ethdev.c b/drivers/net/zxdh/zxdh_ethdev.c
index 974774a2e1..44a50d7dfd 100644
--- a/drivers/net/zxdh/zxdh_ethdev.c
+++ b/drivers/net/zxdh/zxdh_ethdev.c
@@ -1339,6 +1339,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,
@@ -1374,6 +1400,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 5ef00321b0..ecf4c28b0f 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 7936f1b2c8..1a87a2e201 100644
--- a/drivers/net/zxdh/zxdh_ethdev_ops.h
+++ b/drivers/net/zxdh/zxdh_ethdev_ops.h
@@ -102,5 +102,8 @@ void zxdh_data_hi_to_lo(uint64_t *data);
 int32_t zxdh_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat 
*xstats, uint32_t n);
 int32_t zxdh_dev_xstats_get_names(struct rte_eth_dev *dev,
                        struct rte_eth_xstat_name *xstats_names, unsigned int 
limit);
+int zxdh_dev_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t 
fw_size);
+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 884ae5d8c9..d5722838ae 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,
 };
@@ -341,6 +360,20 @@ struct zxdh_mac_reply_msg {
        uint8_t mac_flag;
 };
 
+struct 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];
+};
+
+struct zxdh_flash_msg {
+       uint8_t firmware_version[ZXDH_FWVERS_LEN];
+};
+
+
 struct zxdh_msg_reply_body {
        enum zxdh_reps_flag flag;
        union {
@@ -351,6 +384,8 @@ struct zxdh_msg_reply_body {
                struct zxdh_rss_hf rss_hf;
                struct zxdh_hw_vqm_stats vqm_stats;
                struct zxdh_mac_reply_msg mac_reply_msg;
+               struct zxdh_flash_msg flash_msg;
+               struct zxdh_mac_module_eeprom_msg module_eeprom_msg;
        };
 };
 
@@ -437,6 +472,7 @@ struct 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;
        } data;
 };
 
-- 
2.27.0

Reply via email to