add support ops to set link speed in usermode, and<br />get autoneg stats.<br /> <br />Signed-off-by: Junlong Wang <wang.junlong1@zte.com.cn> <br />---<br /> drivers/net/zxdh/zxdh_ethdev.c     |   6 ++<br /> drivers/net/zxdh/zxdh_ethdev.h     |   7 +-<br /> drivers/net/zxdh/zxdh_ethdev_ops.c | 116 ++++++++++++++++++++++++++---<br /> drivers/net/zxdh/zxdh_ethdev_ops.h |  15 ++++<br /> drivers/net/zxdh/zxdh_msg.c        |  49 ++++++++++++<br /> drivers/net/zxdh/zxdh_msg.h        |  24 +++++-<br /> 6 files changed, 202 insertions(+), 15 deletions(-)<br /> <br />diff --git a/drivers/net/zxdh/zxdh_ethdev.c b/drivers/net/zxdh/zxdh_ethdev.c<br />index 2fc2d78aff..823b1ffb5c 100644<br />--- a/drivers/net/zxdh/zxdh_ethdev.c<br />+++ b/drivers/net/zxdh/zxdh_ethdev.c<br />@@ -1432,6 +1432,10 @@ zxdh_dev_start(struct rte_eth_dev *dev)<br />         zxdh_queue_notify(vq);<br />     }<br />  <br />+    if (hw->is_pf)<br />+        zxdh_link_speed_set(dev);<br />+    zxdh_autoneg_stats_get(dev);<br />+<br />     hw->admin_status = RTE_ETH_LINK_UP;<br />     zxdh_dev_link_update(dev, 0);<br />  <br />@@ -1604,6 +1608,8 @@ zxdh_agent_comm(struct rte_eth_dev *eth_dev, struct zxdh_hw *hw)<br />         return -1;<br />     }<br />  <br />+    zxdh_speed_modes_get(eth_dev);<br />+<br />     if (hw->switchoffload)<br />         hw->phyport = 9;<br />  <br />diff --git a/drivers/net/zxdh/zxdh_ethdev.h b/drivers/net/zxdh/zxdh_ethdev.h<br />index 411d287f32..81b385ecb8 100644<br />--- a/drivers/net/zxdh/zxdh_ethdev.h<br />+++ b/drivers/net/zxdh/zxdh_ethdev.h<br />@@ -125,7 +125,7 @@ struct zxdh_hw {<br />     uint64_t host_features;<br />     uint64_t guest_features;<br />     uint32_t speed;<br />-    uint32_t speed_mode;<br />+    int32_t speed_mode;<br />     uint32_t notify_off_multiplier;<br />     union zxdh_virport_num vport;<br />     uint16_t max_queue_pairs;<br />@@ -173,9 +173,10 @@ struct zxdh_hw {<br />     struct zxdh_vlan_offload_cfg vlan_offload_cfg;<br />     uint16_t queue_pool_count;<br />     uint16_t queue_pool_start;<br />-    uint8_t dl_net_hdr_len;<br />     uint16_t vxlan_fd_num;<br />-    uint8_t rsv1[1];<br />+    uint32_t support_speed_modes;<br />+    uint8_t dl_net_hdr_len;<br />+    uint8_t autoneg;<br />  <br />     struct dh_flow_list dh_flow_list;<br /> };<br />diff --git a/drivers/net/zxdh/zxdh_ethdev_ops.c b/drivers/net/zxdh/zxdh_ethdev_ops.c<br />index cabf81107e..8fb315eeac 100644<br />--- a/drivers/net/zxdh/zxdh_ethdev_ops.c<br />+++ b/drivers/net/zxdh/zxdh_ethdev_ops.c<br />@@ -307,7 +307,7 @@ zxdh_link_info_get(struct rte_eth_dev *dev, struct rte_eth_link *link)<br />         }<br />  <br />         link->link_speed = ZXDH_GET(link_info_msg, link_msg_addr, speed);<br />-        link->link_autoneg = ZXDH_GET(link_info_msg, link_msg_addr, autoneg);<br />+        // link->link_autoneg = ZXDH_GET(link_info_msg, link_msg_addr, autoneg);<br />         hw->speed_mode = ZXDH_GET(link_info_msg, link_msg_addr, speed_modes);<br />         if ((ZXDH_GET(link_info_msg, link_msg_addr, duplex) & RTE_ETH_LINK_FULL_DUPLEX) ==<br />                 RTE_ETH_LINK_FULL_DUPLEX)<br />@@ -322,6 +322,7 @@ zxdh_link_info_get(struct rte_eth_dev *dev, struct rte_eth_link *link)<br />         link->link_autoneg = RTE_ETH_LINK_AUTONEG;<br />         link->link_status = RTE_ETH_LINK_UP;<br />     }<br />+    link->link_autoneg = hw->autoneg;<br />     hw->speed = link->link_speed;<br />  <br />     return 0;<br />@@ -368,6 +369,109 @@ int zxdh_dev_set_link_up(struct rte_eth_dev *dev)<br />     return ret;<br /> }<br />  <br />+static int32_t zxdh_speed_mode_to_spm(uint32_t link_speed_modes)<br />+{<br />+    switch (link_speed_modes) {<br />+    case RTE_ETH_LINK_SPEED_1G:   return ZXDH_SPM_SPEED_1X_1G;<br />+    case RTE_ETH_LINK_SPEED_10G:  return ZXDH_SPM_SPEED_1X_10G;<br />+    case RTE_ETH_LINK_SPEED_25G:  return ZXDH_SPM_SPEED_1X_25G;<br />+    case RTE_ETH_LINK_SPEED_50G:  return ZXDH_SPM_SPEED_1X_50G;<br />+    case RTE_ETH_LINK_SPEED_100G: return ZXDH_SPM_SPEED_4X_100G;<br />+    case RTE_ETH_LINK_SPEED_200G: return ZXDH_SPM_SPEED_4X_200G;<br />+    default: return -1;<br />+    }<br />+}<br />+<br />+int32_t zxdh_link_speed_set(struct rte_eth_dev *dev)<br />+{<br />+    struct zxdh_hw *hw = dev->data->dev_private;<br />+    struct zxdh_msg_info msg = {0};<br />+    uint8_t zxdh_msg_reply_info[ZXDH_ST_SZ_BYTES(msg_reply_info)] = {0};<br />+    void *reply_body_addr = ZXDH_ADDR_OF(msg_reply_info, zxdh_msg_reply_info, reply_body);<br />+    uint32_t link_speed = 0;<br />+    int32_t spm_speed_modes = 0;<br />+    int32_t ret = 0;<br />+<br />+    spm_speed_modes =<br />+        zxdh_speed_mode_to_spm(dev->data->dev_conf.link_speeds & ~RTE_ETH_LINK_SPEED_FIXED);<br />+    if (spm_speed_modes == -1 || spm_speed_modes == hw->speed_mode) {<br />+        PMD_DRV_LOG(DEBUG, "not need update speed");<br />+        return 0;<br />+    }<br />+    if ((spm_speed_modes & hw->support_speed_modes) == 0)  {<br />+        PMD_DRV_LOG(ERR, "not support configure speed :%d ", link_speed);<br />+        return 0;<br />+    }<br />+<br />+    zxdh_agent_msg_build(hw, ZXDH_MAC_SPEED_SET, &msg);<br />+    msg.data.link_msg.autoneg = 0;<br />+    msg.data.link_msg.speed_modes = spm_speed_modes & hw->support_speed_modes;<br />+<br />+    ret = zxdh_send_msg_to_riscv(dev, &msg, sizeof(struct zxdh_msg_info),<br />+                zxdh_msg_reply_info, ZXDH_ST_SZ_BYTES(msg_reply_info),<br />+                ZXDH_BAR_MODULE_MAC);<br />+    uint8_t flag = ZXDH_GET(msg_reply_body, reply_body_addr, flag);<br />+    if (flag != ZXDH_REPS_SUCC || ret) {<br />+        PMD_DRV_LOG(ERR, "failed to set link speed!");<br />+        return -1;<br />+    }<br />+<br />+    return 0;<br />+}<br />+<br />+void<br />+zxdh_speed_modes_get(struct rte_eth_dev *dev)<br />+{<br />+    struct zxdh_hw *hw = dev->data->dev_private;<br />+    struct zxdh_msg_info msg = {0};<br />+    uint8_t zxdh_msg_reply_info[ZXDH_ST_SZ_BYTES(msg_reply_info)] = {0};<br />+    int32_t ret = 0;<br />+<br />+    if (!hw->is_pf)<br />+        return;<br />+<br />+    msg.agent_msg_head.msg_type = ZXDH_MAC_PHYPORT_INIT;<br />+    msg.agent_msg_head.init = 1;<br />+<br />+    ret = zxdh_send_msg_to_riscv(dev, &msg, sizeof(struct zxdh_msg_info),<br />+                zxdh_msg_reply_info, ZXDH_ST_SZ_BYTES(msg_reply_info),<br />+                ZXDH_BAR_MODULE_MAC);<br />+    if (ret)<br />+        PMD_DRV_LOG(ERR, "Failed to get speed mode info");<br />+<br />+    void *reply_body_addr = ZXDH_ADDR_OF(msg_reply_info, zxdh_msg_reply_info, reply_body);<br />+    void *link_msg_addr = ZXDH_ADDR_OF(msg_reply_body, reply_body_addr, link_msg);<br />+    uint32_t speed_modes = ZXDH_GET(link_info_msg, link_msg_addr, speed_modes);<br />+<br />+    hw->support_speed_modes = speed_modes;<br />+}<br />+<br />+int32_t zxdh_autoneg_stats_get(struct rte_eth_dev *dev)<br />+{<br />+    struct zxdh_hw *hw = dev->data->dev_private;<br />+    struct zxdh_msg_info msg;<br />+    uint8_t zxdh_msg_reply_info[ZXDH_ST_SZ_BYTES(msg_reply_info)] = {0};<br />+    int32_t ret = 0;<br />+<br />+    zxdh_agent_msg_build(hw, ZXDH_MAC_AUTONEG_GET, &msg);<br />+<br />+    ret = zxdh_send_msg_to_riscv(dev, &msg, sizeof(struct zxdh_msg_info),<br />+                zxdh_msg_reply_info, ZXDH_ST_SZ_BYTES(msg_reply_info),<br />+                ZXDH_BAR_MODULE_MAC);<br />+    if (ret) {<br />+        PMD_DRV_LOG(ERR, "Failed to get link autoneg stats!");<br />+        return -1;<br />+    }<br />+    void *reply_body_addr = ZXDH_ADDR_OF(msg_reply_info, zxdh_msg_reply_info, reply_body);<br />+    void *link_addr = ZXDH_ADDR_OF(msg_reply_body, reply_body_addr, link_msg);<br />+    void *link_autoeng_addr = ZXDH_ADDR_OF(link_info_msg, link_addr, autoneg);<br />+<br />+    hw->autoneg = *(uint8_t *)link_autoeng_addr;<br />+    PMD_DRV_LOG(DEBUG, "autoneg stats is: %d", hw->autoneg);<br />+<br />+    return 0;<br />+}<br />+<br /> int32_t zxdh_dev_link_update(struct rte_eth_dev *dev, int32_t wait_to_complete __rte_unused)<br /> {<br />     struct rte_eth_link link;<br />@@ -384,17 +488,7 @@ int32_t zxdh_dev_link_update(struct rte_eth_dev *dev, int32_t wait_to_complete _<br />         PMD_DRV_LOG(ERR, "Failed to get link status from hw");<br />         return ret;<br />     }<br />-    link.link_status &= hw->admin_status;<br />-    if (link.link_status == RTE_ETH_LINK_DOWN) {<br />-        PMD_DRV_LOG(DEBUG, "dev link status is down.");<br />-        goto link_down;<br />-    }<br />-    goto out;<br />  <br />-link_down:<br />-    link.link_status = RTE_ETH_LINK_DOWN;<br />-    link.link_speed  = RTE_ETH_SPEED_NUM_UNKNOWN;<br />-out:<br />     if (link.link_status != dev->data->dev_link.link_status) {<br />         ret = zxdh_config_port_status(dev, link.link_status);<br />         if (ret != 0) {<br />diff --git a/drivers/net/zxdh/zxdh_ethdev_ops.h b/drivers/net/zxdh/zxdh_ethdev_ops.h<br />index 85e926887b..6dfe4be473 100644<br />--- a/drivers/net/zxdh/zxdh_ethdev_ops.h<br />+++ b/drivers/net/zxdh/zxdh_ethdev_ops.h<br />@@ -27,6 +27,18 @@<br /> #define ZXDH_RSS_HF  ((ZXDH_HF_MAC_VLAN_ETH | ZXDH_HF_F3_ETH | ZXDH_HF_F5_ETH))<br />  <br /> #define ZXDH_ETHER_MIN_MTU      68<br />+#define ZXDH_SPM_SPEED_1X_10M          RTE_BIT32(0)<br />+#define ZXDH_SPM_SPEED_1X_100M         RTE_BIT32(1)<br />+#define ZXDH_SPM_SPEED_1X_1G           RTE_BIT32(2)<br />+#define ZXDH_SPM_SPEED_1X_2DOT5G       RTE_BIT32(3)<br />+#define ZXDH_SPM_SPEED_1X_5G           RTE_BIT32(4)<br />+#define ZXDH_SPM_SPEED_1X_10G          RTE_BIT32(5)<br />+#define ZXDH_SPM_SPEED_1X_25G          RTE_BIT32(6)<br />+#define ZXDH_SPM_SPEED_1X_50G          RTE_BIT32(7)<br />+#define ZXDH_SPM_SPEED_2X_100G         RTE_BIT32(8)<br />+#define ZXDH_SPM_SPEED_4X_40G          RTE_BIT32(9)<br />+#define ZXDH_SPM_SPEED_4X_100G         RTE_BIT32(10)<br />+#define ZXDH_SPM_SPEED_4X_200G         RTE_BIT32(11)<br />  <br /> struct zxdh_np_stats_data {<br />     uint64_t n_pkts_dropped;<br />@@ -144,5 +156,8 @@ int zxdh_dev_get_module_info(struct rte_eth_dev *dev, struct rte_eth_dev_module_<br /> int zxdh_dev_get_module_eeprom(struct rte_eth_dev *dev, struct rte_dev_eeprom_info *info);<br /> int zxdh_meter_ops_get(struct rte_eth_dev *dev, void *arg);<br /> uint16_t zxdh_hw_qid_to_logic_qid(struct rte_eth_dev *dev, uint16_t qid);<br />+int32_t zxdh_link_speed_set(struct rte_eth_dev *dev);<br />+void zxdh_speed_modes_get(struct rte_eth_dev *dev);<br />+int32_t zxdh_autoneg_stats_get(struct rte_eth_dev *dev);<br />  <br /> #endif /* ZXDH_ETHDEV_OPS_H */<br />diff --git a/drivers/net/zxdh/zxdh_msg.c b/drivers/net/zxdh/zxdh_msg.c<br />index 196e27f91c..ff2d11706c 100644<br />--- a/drivers/net/zxdh/zxdh_msg.c<br />+++ b/drivers/net/zxdh/zxdh_msg.c<br />@@ -2450,9 +2450,58 @@ pf_recv_bar_msg(void *pay_load, uint16_t len, void *reps_buffer,<br />     return ret;<br /> }<br />  <br />+static int vf_recv_link_state_msg(struct rte_eth_dev *dev, void *payload,<br />+        void *reply_body __rte_unused, uint16_t *reps_len)<br />+{<br />+    struct zxdh_hw *hw = dev->data->dev_private;<br />+    void *link_autoneg_addr = ZXDH_ADDR_OF(zxdh_link_state_msg, payload, autoneg_enable);<br />+<br />+    hw->autoneg = *(uint8_t *)link_autoneg_addr;<br />+    dev->data->dev_link.link_autoneg = hw->autoneg;<br />+    *reps_len = ZXDH_ST_SZ_BYTES(zxdh_link_state_msg);<br />+<br />+    return 0;<br />+}<br />+<br />+static int<br />+vf_recv_bar_msg(void *payload, uint16_t len __rte_unused, void *reps_buffer,<br />+    uint16_t *reps_len, void *eth_dev __rte_unused)<br />+{<br />+    struct zxdh_msg_info *msg_payload = (struct zxdh_msg_info *)payload;<br />+    uint16_t pcieid = msg_payload->msg_to_vf.pcieid;<br />+    uint16_t opcode = msg_payload->msg_to_vf.opcode;<br />+    struct rte_eth_dev *dev = (struct rte_eth_dev *)eth_dev;<br />+    struct zxdh_ifc_msg_reply_body_bits *reply_body;<br />+    reply_body = (struct zxdh_ifc_msg_reply_body_bits *)<br />+        ZXDH_ADDR_OF(msg_reply_body, reps_buffer, flag);<br />+    int32_t ret = 0;<br />+<br />+    if (dev == NULL) {<br />+        PMD_DRV_LOG(ERR, "param invalid, dev is NULL");<br />+        ret = -2;<br />+        return ret;<br />+    }<br />+<br />+    switch (opcode) {<br />+    case ZXDH_SET_VF_LINK_STATE:<br />+        PMD_DRV_LOG(DEBUG, "PF(pcieid:%d ) set VF's link state", pcieid);<br />+        vf_recv_link_state_msg(dev, &msg_payload->data, reps_buffer, reps_len);<br />+        reply_body->flag[0] = ZXDH_REPS_SUCC;<br />+        break;<br />+    default:<br />+        ZXDH_SET(msg_reply_body, reps_buffer, flag, ZXDH_REPS_INVALID);<br />+        PMD_DRV_LOG(ERR, "[VF GET MSG FROM PF]--unknown msg opcode:%d", opcode);<br />+        ret = -1;<br />+        break;<br />+    }<br />+    return ret;<br />+}<br />+<br /> void<br /> zxdh_msg_cb_reg(struct zxdh_hw *hw)<br /> {<br />     if (hw->is_pf)<br />         zxdh_bar_chan_msg_recv_register(ZXDH_MODULE_BAR_MSG_TO_PF, pf_recv_bar_msg);<br />+    else<br />+        zxdh_bar_chan_msg_recv_register(ZXDH_MODULE_BAR_MSG_TO_VF, vf_recv_bar_msg);<br /> }<br />diff --git a/drivers/net/zxdh/zxdh_msg.h b/drivers/net/zxdh/zxdh_msg.h<br />index 61a3da878e..0fc9bff75d 100644<br />--- a/drivers/net/zxdh/zxdh_msg.h<br />+++ b/drivers/net/zxdh/zxdh_msg.h<br />@@ -205,6 +205,8 @@ enum zxdh_module_id {<br /> enum zxdh_agent_msg_type {<br />     ZXDH_MAC_STATS_GET = 10,<br />     ZXDH_MAC_STATS_RESET,<br />+    ZXDH_MAC_PHYPORT_INIT,<br />+    ZXDH_MAC_SPEED_SET,<br />     ZXDH_MAC_LINK_GET = 14,<br />     ZXDH_MAC_MODULE_EEPROM_READ = 20,<br />     ZXDH_VQM_DEV_STATS_GET = 21,<br />@@ -212,6 +214,7 @@ enum zxdh_agent_msg_type {<br />     ZXDH_FLASH_FIR_VERSION_GET = 23,<br />     ZXDH_VQM_QUEUE_STATS_GET = 24,<br />     ZXDH_VQM_QUEUE_STATS_RESET,<br />+    ZXDH_MAC_AUTONEG_GET = 44,<br /> };<br />  <br /> enum zxdh_msg_type {<br />@@ -233,6 +236,7 @@ enum zxdh_msg_type {<br />  <br />     ZXDH_PORT_ATTRS_SET = 25,<br />     ZXDH_PORT_PROMISC_SET = 26,<br />+    ZXDH_SET_VF_LINK_STATE = 28,<br />  <br />     ZXDH_GET_NP_STATS = 31,<br />     ZXDH_PLCR_CAR_PROFILE_ID_ADD = 36,<br />@@ -408,6 +412,17 @@ struct zxdh_ifc_agent_mac_module_eeprom_msg_bits {<br />     uint8_t data[ZXDH_MODULE_EEPROM_DATA_LEN * 8];<br /> };<br />  <br />+struct zxdh_ifc_zxdh_link_state_msg_bits {<br />+    uint8_t is_link_force_set[0x8];<br />+    uint8_t link_forced[0x8];<br />+    uint8_t link_up[0x8];<br />+    uint8_t speed[0x20];<br />+    uint8_t autoneg_enable[0x20];<br />+    uint8_t supported_speed_modes[0x20];<br />+    uint8_t advertising_speed_modes[0x20];<br />+    uint8_t duplex[0x8];<br />+};<br />+<br /> struct zxdh_flash_msg {<br />     uint8_t firmware_version[ZXDH_FWVERS_LEN];<br /> };<br />@@ -454,6 +469,7 @@ struct zxdh_ifc_msg_reply_body_bits {<br />         struct zxdh_ifc_mtr_profile_info_bits  mtr_profile_info;<br />         struct zxdh_ifc_mtr_stats_bits hw_mtr_stats;<br />         struct zxdh_flow_op_rsp  flow_rsp;<br />+        struct zxdh_ifc_zxdh_link_state_msg_bits link_state_msg;<br />     };<br /> };<br />  <br />@@ -482,6 +498,11 @@ struct __rte_packed_begin zxdh_msg_head {<br />     uint16_t pcieid;<br /> } __rte_packed_end;<br />  <br />+struct __rte_packed_begin zxdh_msg_head_to_vf {<br />+    uint8_t opcode;<br />+    uint16_t pcieid;<br />+} __rte_packed_end;<br />+<br /> struct zxdh_port_attr_set_msg {<br />     uint32_t mode;<br />     uint32_t value;<br />@@ -521,7 +542,7 @@ struct zxdh_agent_msg_head {<br />     uint8_t msg_type;<br />     uint8_t panel_id;<br />     uint8_t phyport;<br />-    uint8_t rsv;<br />+    uint8_t init;<br />     uint16_t vf_id;<br />     uint16_t pcie_id;<br /> };<br />@@ -570,6 +591,7 @@ struct zxdh_msg_info {<br />         uint8_t head_len[ZXDH_MSG_HEAD_LEN];<br />         struct zxdh_msg_head msg_head;<br />         struct zxdh_agent_msg_head agent_msg_head;<br />+        struct zxdh_msg_head_to_vf msg_to_vf;<br />     };<br />     union {<br />         uint8_t datainfo[ZXDH_MSG_REQ_BODY_MAX_LEN];<br />--  <br />2.27.0<br />