optimize mac(add/remove/del) ops.<br /> <br />Signed-off-by: Junlong Wang <wang.junlong1@zte.com.cn> <br />---<br /> drivers/net/zxdh/zxdh_ethdev.c     |  40 +++++++++-<br /> drivers/net/zxdh/zxdh_ethdev.h     |  13 +++-<br /> drivers/net/zxdh/zxdh_ethdev_ops.c |  59 +++++++++------<br /> drivers/net/zxdh/zxdh_msg.c        | 118 +++++++++++++++++++++++++++++<br /> drivers/net/zxdh/zxdh_msg.h        |   7 ++<br /> drivers/net/zxdh/zxdh_tables.c     |  70 +++++++++++------<br /> drivers/net/zxdh/zxdh_tables.h     |  11 +--<br /> 7 files changed, 263 insertions(+), 55 deletions(-)<br /> <br />diff --git a/drivers/net/zxdh/zxdh_ethdev.c b/drivers/net/zxdh/zxdh_ethdev.c<br />index 6ac8df4b0d..9393712a31 100644<br />--- a/drivers/net/zxdh/zxdh_ethdev.c<br />+++ b/drivers/net/zxdh/zxdh_ethdev.c<br />@@ -1157,8 +1157,8 @@ zxdh_mac_config(struct rte_eth_dev *eth_dev)<br />     int ret = 0;<br />  <br />     if (hw->is_pf) {<br />-        ret = zxdh_set_mac_table(hw, hw->vport.vport,<br />-                &eth_dev->data->mac_addrs[0], hw->hash_search_index);<br />+        ret = zxdh_add_mac_table(hw, hw->vport.vport,<br />+                &eth_dev->data->mac_addrs[0], hw->hash_search_index, 0, 0);<br />         if (ret) {<br />             PMD_DRV_LOG(ERR, "Failed to add mac: port 0x%x", hw->vport.vport);<br />             return ret;<br />@@ -1592,6 +1592,39 @@ zxdh_queue_res_get(struct rte_eth_dev *eth_dev)<br />         hw->queue_pool_start = 0;<br /> }<br />  <br />+static int<br />+zxdh_priv_res_init(struct zxdh_hw *hw)<br />+{<br />+    if (hw->is_pf) {<br />+        hw->vfinfo = rte_zmalloc("vfinfo", ZXDH_MAX_VF * sizeof(struct vfinfo), 4);<br />+        if (hw->vfinfo == NULL) {<br />+            PMD_DRV_LOG(ERR, "vfinfo malloc failed");<br />+            return -ENOMEM;<br />+        }<br />+    } else {<br />+        hw->vfinfo = NULL;<br />+    }<br />+<br />+    hw->channel_context = rte_zmalloc("zxdh_chnlctx",<br />+            sizeof(struct zxdh_chnl_context) * ZXDH_QUEUES_NUM_MAX, 0);<br />+    if (hw->channel_context == NULL) {<br />+        PMD_DRV_LOG(ERR, "Failed to allocate channel_context");<br />+        return -ENOMEM;<br />+    }<br />+    return 0;<br />+}<br />+<br />+static void<br />+zxdh_priv_res_free(struct zxdh_hw *priv)<br />+{<br />+    rte_free(priv->vfinfo);<br />+    priv->vfinfo = NULL;<br />+    if (priv->channel_context != NULL) {<br />+        rte_free(priv->channel_context);<br />+        priv->channel_context = NULL;<br />+    }<br />+}<br />+<br /> static int<br /> zxdh_eth_dev_init(struct rte_eth_dev *eth_dev)<br /> {<br />@@ -1667,6 +1700,8 @@ zxdh_eth_dev_init(struct rte_eth_dev *eth_dev)<br />  <br />     zxdh_queue_res_get(eth_dev);<br />     zxdh_msg_cb_reg(hw);<br />+    if (zxdh_priv_res_init(hw) != 0)<br />+        goto err_zxdh_init;<br />     ret = zxdh_configure_intr(eth_dev);<br />     if (ret != 0)<br />         goto err_zxdh_init;<br />@@ -1681,6 +1716,7 @@ zxdh_eth_dev_init(struct rte_eth_dev *eth_dev)<br />     zxdh_intr_release(eth_dev);<br />     zxdh_np_uninit(eth_dev);<br />     zxdh_bar_msg_chan_exit();<br />+    zxdh_priv_res_free(hw);<br />     rte_free(eth_dev->data->mac_addrs);<br />     eth_dev->data->mac_addrs = NULL;<br />     return ret;<br />diff --git a/drivers/net/zxdh/zxdh_ethdev.h b/drivers/net/zxdh/zxdh_ethdev.h<br />index 7fe561ae24..deebf075cc 100644<br />--- a/drivers/net/zxdh/zxdh_ethdev.h<br />+++ b/drivers/net/zxdh/zxdh_ethdev.h<br />@@ -41,6 +41,7 @@<br />  <br /> #define ZXDH_MAX_NAME_LEN               32<br /> #define ZXDH_SLOT_MAX             256<br />+#define ZXDH_MAX_VF               256<br />  <br /> union zxdh_virport_num {<br />     uint16_t vport;<br />@@ -66,6 +67,15 @@ struct zxdh_vlan_offload_cfg {<br />     uint8_t resv:4;<br /> };<br />  <br />+struct vfinfo {<br />+    uint16_t vf_idx;<br />+    uint16_t pcieid;<br />+    uint16_t vport;<br />+    uint8_t flag;<br />+    uint8_t state;<br />+    struct rte_ether_addr vf_mac[ZXDH_MAX_MAC_ADDRS];<br />+};<br />+<br /> struct zxdh_hw {<br />     struct rte_eth_dev *eth_dev;<br />     struct zxdh_pci_common_cfg *common_cfg;<br />@@ -73,8 +83,9 @@ struct zxdh_hw {<br />     struct rte_intr_handle *risc_intr;<br />     struct rte_intr_handle *dtb_intr;<br />     struct zxdh_virtqueue **vqs;<br />-    struct zxdh_chnl_context channel_context[ZXDH_QUEUES_NUM_MAX];<br />+    struct zxdh_chnl_context *channel_context;<br />     struct zxdh_dev_shared_data *dev_sd;<br />+    struct vfinfo *vfinfo;<br />  <br />     uint64_t bar_addr[ZXDH_NUM_BARS];<br />     uint64_t host_features;<br />diff --git a/drivers/net/zxdh/zxdh_ethdev_ops.c b/drivers/net/zxdh/zxdh_ethdev_ops.c<br />index bb9d291181..25a33ed493 100644<br />--- a/drivers/net/zxdh/zxdh_ethdev_ops.c<br />+++ b/drivers/net/zxdh/zxdh_ethdev_ops.c<br />@@ -293,7 +293,8 @@ int zxdh_dev_set_link_down(struct rte_eth_dev *dev)<br />     return ret;<br /> }<br />  <br />-int zxdh_dev_mac_addr_set(struct rte_eth_dev *dev, struct rte_ether_addr *addr)<br />+int<br />+zxdh_dev_mac_addr_set(struct rte_eth_dev *dev, struct rte_ether_addr *addr)<br /> {<br />     struct zxdh_hw *hw = (struct zxdh_hw *)dev->data->dev_private;<br />     struct rte_ether_addr *old_addr = &dev->data->mac_addrs[0];<br />@@ -304,54 +305,63 @@ int zxdh_dev_mac_addr_set(struct rte_eth_dev *dev, struct rte_ether_addr *addr)<br />         PMD_DRV_LOG(ERR, "mac address is invalid!");<br />         return -EINVAL;<br />     }<br />+    if (rte_is_same_ether_addr(old_addr, addr))<br />+        return 0;<br />  <br />     if (hw->is_pf) {<br />-        ret = zxdh_del_mac_table(hw, hw->vport.vport, old_addr, hw->hash_search_index);<br />+        ret = zxdh_add_mac_table(hw, hw->vport.vport, addr, hw->hash_search_index, 0, 0);<br />         if (ret) {<br />+            if (ret == ZXDH_EEXIST_MAC_FLAG) {<br />+                PMD_DRV_LOG(ERR, "pf mac add failed! mac is in used, code:%d", ret);<br />+                return -EADDRINUSE;<br />+            }<br />             PMD_DRV_LOG(ERR, "mac_addr_add failed, code:%d", ret);<br />             return ret;<br />         }<br />-        hw->uc_num--;<br />+        hw->uc_num++;<br />  <br />-        ret = zxdh_set_mac_table(hw, hw->vport.vport, addr, hw->hash_search_index);<br />+        ret = zxdh_del_mac_table(hw, hw->vport.vport, old_addr,<br />+            hw->hash_search_index, 0, 0);<br />         if (ret) {<br />             PMD_DRV_LOG(ERR, "mac_addr_add failed, code:%d", ret);<br />             return ret;<br />         }<br />-        hw->uc_num++;<br />+        hw->uc_num--;<br />     } else {<br />         struct zxdh_mac_filter *mac_filter = &msg_info.data.mac_filter_msg;<br />-<br />         mac_filter->filter_flag = ZXDH_MAC_UNFILTER;<br />-        mac_filter->mac_flag = true;<br />-        rte_memcpy(&mac_filter->mac, old_addr, sizeof(struct rte_ether_addr));<br />-        zxdh_msg_head_build(hw, ZXDH_MAC_DEL, &msg_info);<br />+        rte_memcpy(&mac_filter->mac, addr, sizeof(struct rte_ether_addr));<br />+        zxdh_msg_head_build(hw, ZXDH_MAC_ADD, &msg_info);<br />         ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(msg_info), NULL, 0);<br />         if (ret) {<br />+            if (ret == ZXDH_EEXIST_MAC_FLAG) {<br />+                PMD_DRV_LOG(ERR, "pf mac add failed! mac is in used, code:%d", ret);<br />+                return -EADDRINUSE;<br />+            }<br />             PMD_DRV_LOG(ERR, "Failed to send msg: port 0x%x msg type %d",<br />-                hw->vport.vport, ZXDH_MAC_DEL);<br />+                hw->vport.vport, ZXDH_MAC_ADD);<br />             return ret;<br />         }<br />-        hw->uc_num--;<br />-        PMD_DRV_LOG(INFO, "Success to send msg: port 0x%x msg type %d",<br />-            hw->vport.vport, ZXDH_MAC_DEL);<br />+        hw->uc_num++;<br />  <br />         mac_filter->filter_flag = ZXDH_MAC_UNFILTER;<br />-        rte_memcpy(&mac_filter->mac, addr, sizeof(struct rte_ether_addr));<br />-        zxdh_msg_head_build(hw, ZXDH_MAC_ADD, &msg_info);<br />+        mac_filter->mac_flag = true;<br />+        rte_memcpy(&mac_filter->mac, old_addr, sizeof(struct rte_ether_addr));<br />+        zxdh_msg_head_build(hw, ZXDH_MAC_DEL, &msg_info);<br />         ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(msg_info), NULL, 0);<br />         if (ret) {<br />             PMD_DRV_LOG(ERR, "Failed to send msg: port 0x%x msg type %d",<br />-                hw->vport.vport, ZXDH_MAC_ADD);<br />+                hw->vport.vport, ZXDH_MAC_DEL);<br />             return ret;<br />         }<br />-        hw->uc_num++;<br />+        hw->uc_num--;<br />     }<br />     rte_ether_addr_copy(addr, (struct rte_ether_addr *)hw->mac_addr);<br />     return ret;<br /> }<br />  <br />-int zxdh_dev_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,<br />+int<br />+zxdh_dev_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,<br />     uint32_t index, uint32_t vmdq __rte_unused)<br /> {<br />     struct zxdh_hw *hw = dev->data->dev_private;<br />@@ -374,12 +384,13 @@ int zxdh_dev_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac_ad<br />     if (hw->is_pf) {<br />         if (rte_is_unicast_ether_addr(mac_addr)) {<br />             if (hw->uc_num < ZXDH_MAX_UC_MAC_ADDRS) {<br />-                ret = zxdh_set_mac_table(hw, hw->vport.vport,<br />-                        mac_addr, hw->hash_search_index);<br />+                ret = zxdh_add_mac_table(hw, hw->vport.vport,<br />+                            mac_addr, hw->hash_search_index, 0, 0);<br />                 if (ret) {<br />                     PMD_DRV_LOG(ERR, "mac_addr_add failed, code:%d", ret);<br />                     return ret;<br />                 }<br />+                memcpy(&hw->mac_addr, mac_addr, 6);<br />                 hw->uc_num++;<br />             } else {<br />                 PMD_DRV_LOG(ERR, "MC_MAC is out of range, MAX_MC_MAC:%d",<br />@@ -388,8 +399,8 @@ int zxdh_dev_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac_ad<br />             }<br />         } else {<br />             if (hw->mc_num < ZXDH_MAX_MC_MAC_ADDRS) {<br />-                ret = zxdh_set_mac_table(hw, hw->vport.vport,<br />-                        mac_addr, hw->hash_search_index);<br />+                ret = zxdh_add_mac_table(hw, hw->vport.vport,<br />+                            mac_addr, hw->hash_search_index, 0, 0);<br />                 if (ret) {<br />                     PMD_DRV_LOG(ERR, "mac_addr_add  failed, code:%d", ret);<br />                     return ret;<br />@@ -457,7 +468,7 @@ void zxdh_dev_mac_addr_remove(struct rte_eth_dev *dev __rte_unused, uint32_t ind<br />         if (rte_is_unicast_ether_addr(mac_addr)) {<br />             if (hw->uc_num <= ZXDH_MAX_UC_MAC_ADDRS) {<br />                 ret = zxdh_del_mac_table(hw, hw->vport.vport,<br />-                        mac_addr, hw->hash_search_index);<br />+                        mac_addr, hw->hash_search_index, 0, 0);<br />                 if (ret) {<br />                     PMD_DRV_LOG(ERR, "mac_addr_del  failed, code:%d", ret);<br />                     return;<br />@@ -471,7 +482,7 @@ void zxdh_dev_mac_addr_remove(struct rte_eth_dev *dev __rte_unused, uint32_t ind<br />         } else {<br />             if (hw->mc_num <= ZXDH_MAX_MC_MAC_ADDRS) {<br />                 ret = zxdh_del_mac_table(hw, hw->vport.vport,<br />-                            mac_addr, hw->hash_search_index);<br />+                            mac_addr, hw->hash_search_index, 0, 0);<br />                 if (ret) {<br />                     PMD_DRV_LOG(ERR, "mac_addr_del  failed, code:%d", ret);<br />                     return;<br />diff --git a/drivers/net/zxdh/zxdh_msg.c b/drivers/net/zxdh/zxdh_msg.c<br />index c109a3601d..aa93c4c26a 100644<br />--- a/drivers/net/zxdh/zxdh_msg.c<br />+++ b/drivers/net/zxdh/zxdh_msg.c<br />@@ -1270,6 +1270,28 @@ zxdh_vf_port_init(struct zxdh_hw *pf_hw, uint16_t vport, void *cfg_data,<br />     return ret;<br /> }<br />  <br />+static int<br />+zxdh_mac_clear(struct zxdh_hw *hw, union zxdh_virport_num vport)<br />+{<br />+    uint16_t vf_id = vport.vfid;<br />+    int i;<br />+    int ret = 0;<br />+<br />+    for (i = 0; (i != ZXDH_MAX_MAC_ADDRS); ++i) {<br />+        if (!rte_is_zero_ether_addr(&hw->vfinfo[vf_id].vf_mac[i])) {<br />+            ret = zxdh_del_mac_table(hw, vport.vport,<br />+                    &hw->vfinfo[vf_id].vf_mac[i],<br />+                    hw->hash_search_index, 0, 0);<br />+            if (ret) {<br />+                PMD_DRV_LOG(ERR, "vf_del_mac_failed. code:%d", ret);<br />+                return ret;<br />+            }<br />+            memset(&hw->vfinfo[vf_id].vf_mac[i], 0, sizeof(struct rte_ether_addr));<br />+        }<br />+    }<br />+    return ret;<br />+}<br />+<br /> static int<br /> zxdh_vf_port_uninit(struct zxdh_hw *pf_hw,<br />         uint16_t vport, void *cfg_data __rte_unused,<br />@@ -1278,6 +1300,7 @@ zxdh_vf_port_uninit(struct zxdh_hw *pf_hw,<br /> {<br />     char str[ZXDH_MSG_REPLY_BODY_MAX_LEN] = "uninit";<br />     struct zxdh_port_attr_table port_attr = {0};<br />+    union zxdh_virport_num vport_num = {.vport = vport};<br />     int ret = 0;<br />  <br />     *res_len =  ZXDH_MSG_REPLYBODY_HEAD;<br />@@ -1289,6 +1312,12 @@ zxdh_vf_port_uninit(struct zxdh_hw *pf_hw,<br />         goto proc_end;<br />     }<br />  <br />+    ret = zxdh_mac_clear(pf_hw, vport_num);<br />+    if (ret) {<br />+        PMD_DRV_LOG(ERR, "zxdh_mac_clear failed, code:%d", ret);<br />+        goto proc_end;<br />+    }<br />+<br />     *res_len += strlen(str);<br />     rte_memcpy(&res_info->reply_data, str, strlen(str) + 1);<br />     res_info->flag = ZXDH_REPS_SUCC;<br />@@ -1301,10 +1330,99 @@ zxdh_vf_port_uninit(struct zxdh_hw *pf_hw,<br />     return ret;<br /> }<br />  <br />+static int<br />+zxdh_add_vf_mac_table(struct zxdh_hw *hw, uint16_t vport, void *cfg_data,<br />+        struct zxdh_msg_reply_body *reply_body, uint16_t *reply_len)<br />+{<br />+    char str[ZXDH_MSG_REPLY_BODY_MAX_LEN] = "add mac";<br />+    union zxdh_virport_num port = {0};<br />+    struct zxdh_mac_filter *mac_filter = (struct zxdh_mac_filter *)cfg_data;<br />+    struct rte_ether_addr *addr = &mac_filter->mac;<br />+    int i = 0, ret = 0;<br />+    uint16_t vf_id = port.vfid;<br />+    port.vport = vport;<br />+<br />+    for (i = 0; i < ZXDH_MAX_MAC_ADDRS; i++)<br />+        if (rte_is_same_ether_addr(&hw->vfinfo[vf_id].vf_mac[i], addr))<br />+            goto success;<br />+<br />+    ret = zxdh_add_mac_table(hw, vport, addr, hw->hash_search_index, 0, 0);<br />+    if (ret == -EADDRINUSE) {<br />+        reply_body->mac_reply_msg.mac_flag = ZXDH_EEXIST_MAC_FLAG;<br />+        PMD_DRV_LOG(ERR, "vf vport 0x%x set mac ret 0x%x failed. mac is in used.",<br />+                port.vport, ret);<br />+        goto failure;<br />+    }<br />+    if (ret) {<br />+        sprintf(str, "[PF GET MSG FROM VF]--VF add mac failed. code:%d\n", ret);<br />+        PMD_DRV_LOG(ERR, " %s", str);<br />+        goto failure;<br />+    }<br />+    for (i = 0; i < ZXDH_MAX_MAC_ADDRS; i++) {<br />+        if (rte_is_zero_ether_addr(&hw->vfinfo[vf_id].vf_mac[i])) {<br />+            memcpy(&hw->vfinfo[vf_id].vf_mac[i], addr, 6);<br />+            break;<br />+        }<br />+    }<br />+<br />+success:<br />+    sprintf(str, " vport 0x%x set mac ret 0x%x\n", port.vport, ret);<br />+    *reply_len =  strlen(str) + ZXDH_MSG_REPLYBODY_HEAD;<br />+    rte_memcpy(&reply_body->reply_data, str, strlen(str) + 1);<br />+    reply_body->flag = ZXDH_REPS_SUCC;<br />+    PMD_DRV_LOG(DEBUG, " reply len %d", *reply_len);<br />+    return ret;<br />+<br />+failure:<br />+    *reply_len = strlen(str) + ZXDH_MSG_REPLYBODY_HEAD;<br />+    reply_body->flag = ZXDH_REPS_FAIL;<br />+    return ret;<br />+}<br />+<br />+static int<br />+zxdh_del_vf_mac_table(struct zxdh_hw *hw, uint16_t vport, void *cfg_data,<br />+    struct zxdh_msg_reply_body *res_info, uint16_t *res_len)<br />+{<br />+    int ret, i = 0;<br />+    struct zxdh_mac_filter *mac_filter = (struct zxdh_mac_filter *)cfg_data;<br />+    union zxdh_virport_num  port = (union zxdh_virport_num)vport;<br />+    char str[ZXDH_MSG_REPLY_BODY_MAX_LEN] = "del mac";<br />+    uint16_t  vf_id = port.vfid;<br />+<br />+    PMD_DRV_LOG(DEBUG, "[PF GET MSG FROM VF]--vf mac to del.");<br />+    ret = zxdh_del_mac_table(hw, vport, &mac_filter->mac, hw->hash_search_index, 0, 0);<br />+    if (ret == -EADDRINUSE)<br />+        ret = 0;<br />+<br />+    if (ret) {<br />+        sprintf(str, "[PF GET MSG FROM VF]--VF del mac failed. code:%d\n", ret);<br />+        PMD_DRV_LOG(ERR, "%s", str);<br />+        goto proc_end;<br />+    }<br />+<br />+    for (i = 0; i < ZXDH_MAX_MAC_ADDRS; i++) {<br />+        if (rte_is_same_ether_addr(&hw->vfinfo[vf_id].vf_mac[i], &mac_filter->mac))<br />+            memset(&hw->vfinfo[vf_id].vf_mac[i], 0, sizeof(struct rte_ether_addr));<br />+    }<br />+<br />+    sprintf(str, "vport 0x%x del mac ret 0x%x\n", port.vport, ret);<br />+    *res_len =  strlen(str) + ZXDH_MSG_REPLYBODY_HEAD;<br />+    rte_memcpy(&res_info->reply_data, str, strlen(str) + 1);<br />+    res_info->flag = ZXDH_REPS_SUCC;<br />+    return ret;<br />+<br />+proc_end:<br />+    *res_len = strlen(str) + ZXDH_MSG_REPLYBODY_HEAD;<br />+    res_info->flag = ZXDH_REPS_FAIL;<br />+    return ret;<br />+}<br />+<br /> zxdh_msg_process_callback zxdh_proc_cb[] = {<br />     [ZXDH_NULL] = NULL,<br />     [ZXDH_VF_PORT_INIT] = zxdh_vf_port_init,<br />     [ZXDH_VF_PORT_UNINIT] = zxdh_vf_port_uninit,<br />+    [ZXDH_MAC_ADD] = zxdh_add_vf_mac_table,<br />+    [ZXDH_MAC_DEL] = zxdh_del_vf_mac_table,<br /> };<br />  <br /> static inline int<br />diff --git a/drivers/net/zxdh/zxdh_msg.h b/drivers/net/zxdh/zxdh_msg.h<br />index afe0474ebc..51b693bf86 100644<br />--- a/drivers/net/zxdh/zxdh_msg.h<br />+++ b/drivers/net/zxdh/zxdh_msg.h<br />@@ -59,6 +59,8 @@<br /> #define ZXDH_VLAN_STRIP_MSG_TYPE   0<br /> #define ZXDH_QINQ_STRIP_MSG_TYPE   1<br />  <br />+#define ZXDH_EEXIST_MAC_FLAG       0xFD<br />+<br /> enum ZXDH_DRIVER_TYPE {<br />     ZXDH_MSG_CHAN_END_MPF = 0,<br />     ZXDH_MSG_CHAN_END_PF,<br />@@ -301,6 +303,10 @@ struct zxdh_offset_get_msg {<br />     uint16_t type;<br /> };<br />  <br />+struct zxdh_mac_reply_msg {<br />+    uint8_t mac_flag;<br />+};<br />+<br /> struct __rte_packed_begin zxdh_msg_reply_head {<br />     uint8_t flag;<br />     uint16_t reps_len;<br />@@ -334,6 +340,7 @@ struct __rte_packed_begin zxdh_msg_reply_body {<br />     enum zxdh_reps_flag flag;<br />     union __rte_packed_begin {<br />         uint8_t reply_data[ZXDH_MSG_REPLY_BODY_MAX_LEN - sizeof(enum zxdh_reps_flag)];<br />+        struct zxdh_mac_reply_msg mac_reply_msg;<br />         struct zxdh_hw_np_stats np_stats;<br />         struct zxdh_link_info_msg link_msg;<br />         struct zxdh_rss_reta rss_reta;<br />diff --git a/drivers/net/zxdh/zxdh_tables.c b/drivers/net/zxdh/zxdh_tables.c<br />index a5d598d022..bfc240a051 100644<br />--- a/drivers/net/zxdh/zxdh_tables.c<br />+++ b/drivers/net/zxdh/zxdh_tables.c<br />@@ -232,20 +232,20 @@ zxdh_delete_port_attr(struct zxdh_hw *hw, uint16_t vport,<br /> }<br />  <br /> int<br />-zxdh_set_mac_table(struct zxdh_hw *hw, uint16_t vport,<br />-        struct rte_ether_addr *addr, uint8_t hash_search_idx)<br />+zxdh_add_mac_table(struct zxdh_hw *hw, uint16_t vport, struct rte_ether_addr *addr,<br />+        uint8_t hash_search_idx, uint16_t srv_tpid, uint16_t srv_vlanid)<br /> {<br />-    struct zxdh_dtb_shared_data *dtb_data = &hw->dev_sd->dtb_sd;<br />     struct zxdh_mac_unicast_table unicast_table = {0};<br />     struct zxdh_mac_multicast_table multicast_table = {0};<br />     union zxdh_virport_num vport_num = (union zxdh_virport_num)vport;<br />     uint32_t ret;<br />     uint16_t group_id = 0;<br />+    uint16_t vfid = vport_num.vfid;<br />  <br />     if (rte_is_unicast_ether_addr(addr)) {<br />         rte_memcpy(unicast_table.key.dmac_addr, addr, sizeof(struct rte_ether_addr));<br />-        unicast_table.entry.hit_flag = 0;<br />-        unicast_table.entry.vfid = vport_num.vfid;<br />+        unicast_table.key.sriov_vlan_tpid = srv_tpid;<br />+        unicast_table.key.sriov_vlan_id = srv_vlanid;<br />  <br />         ZXDH_DTB_HASH_ENTRY_INFO_T dtb_hash_entry = {<br />             .p_actu_key = (uint8_t *)&unicast_table.key,<br />@@ -256,8 +256,24 @@ zxdh_set_mac_table(struct zxdh_hw *hw, uint16_t vport,<br />             .p_entry_data = (void *)&dtb_hash_entry<br />         };<br />  <br />+        ret = zxdh_np_dtb_table_entry_get(hw->slot_id, hw->dev_sd->dtb_sd.queueid,<br />+                &entry_get, 1);<br />+        if (ret == 0) {<br />+            if (unicast_table.entry.hit_flag != 0 && <br />+                    rte_be_to_cpu_16(unicast_table.entry.vfid) != vfid) {<br />+                return -EADDRINUSE;<br />+            } else if (unicast_table.entry.hit_flag != 0 && <br />+                    rte_be_to_cpu_16(unicast_table.entry.vfid) == vfid) {<br />+                PMD_DRV_LOG(DEBUG, "vfid:%d, equals to itself mac, ret:%d",<br />+                    vfid, ret);<br />+                return 0;<br />+            }<br />+        }<br />+<br />+        unicast_table.entry.vfid = rte_cpu_to_be_16(vfid);<br />+        unicast_table.entry.hit_flag = 1;<br />         ret = zxdh_np_dtb_table_entry_write(hw->slot_id,<br />-                    dtb_data->queueid, 1, &entry_get);<br />+                    hw->dev_sd->dtb_sd.queueid, 1, &entry_get);<br />         if (ret) {<br />             PMD_DRV_LOG(ERR, "Insert mac_table failed");<br />             return -ret;<br />@@ -277,7 +293,7 @@ zxdh_set_mac_table(struct zxdh_hw *hw, uint16_t vport,<br />                 .p_entry_data = (void *)&dtb_hash_entry<br />             };<br />  <br />-            ret = zxdh_np_dtb_table_entry_get(hw->slot_id, dtb_data->queueid,<br />+            ret = zxdh_np_dtb_table_entry_get(hw->slot_id, hw->dev_sd->dtb_sd.queueid,<br />                     &entry_get, 1);<br />             uint8_t index = (vport_num.vfid % 64) / 32;<br />             if (ret == 0) {<br />@@ -308,8 +324,7 @@ zxdh_set_mac_table(struct zxdh_hw *hw, uint16_t vport,<br />                         multicast_table.entry.mc_pf_enable = false;<br />                 }<br />             }<br />-<br />-            ret = zxdh_np_dtb_table_entry_write(hw->slot_id, dtb_data->queueid,<br />+            ret = zxdh_np_dtb_table_entry_write(hw->slot_id, hw->dev_sd->dtb_sd.queueid,<br />                         1, &entry_get);<br />             if (ret) {<br />                 PMD_DRV_LOG(ERR, "add mac_table failed, code:%d", ret);<br />@@ -321,20 +336,21 @@ zxdh_set_mac_table(struct zxdh_hw *hw, uint16_t vport,<br /> }<br />  <br /> int<br />-zxdh_del_mac_table(struct zxdh_hw *hw, uint16_t vport,<br />-        struct rte_ether_addr *addr, uint8_t hash_search_idx)<br />+zxdh_del_mac_table(struct zxdh_hw *hw, uint16_t vport, struct rte_ether_addr *addr,<br />+        uint8_t hash_search_idx, uint16_t srv_tpid, uint16_t srv_vlanid)<br /> {<br />-    struct zxdh_dtb_shared_data *dtb_data = &hw->dev_sd->dtb_sd;<br />     struct zxdh_mac_unicast_table unicast_table = {0};<br />     struct zxdh_mac_multicast_table multicast_table = {0};<br />     union zxdh_virport_num vport_num = (union zxdh_virport_num)vport;<br />     uint32_t ret, del_flag = 0;<br />     uint16_t group_id = 0;<br />+    union zxdh_virport_num port = (union zxdh_virport_num)vport;<br />+    uint16_t vfid = zxdh_vport_to_vfid(port);<br />  <br />     if (rte_is_unicast_ether_addr(addr)) {<br />         rte_memcpy(unicast_table.key.dmac_addr, addr, sizeof(struct rte_ether_addr));<br />-        unicast_table.entry.hit_flag = 0;<br />-        unicast_table.entry.vfid = vport_num.vfid;<br />+        unicast_table.key.sriov_vlan_id = srv_vlanid;<br />+        unicast_table.key.sriov_vlan_tpid = srv_tpid;<br />  <br />         ZXDH_DTB_HASH_ENTRY_INFO_T dtb_hash_entry = {<br />             .p_actu_key = (uint8_t *)&unicast_table.key,<br />@@ -345,9 +361,17 @@ zxdh_del_mac_table(struct zxdh_hw *hw, uint16_t vport,<br />             .sdt_no = ZXDH_MAC_HASH_INDEX(hash_search_idx),<br />             .p_entry_data = (void *)&dtb_hash_entry<br />         };<br />+        ret = zxdh_np_dtb_table_entry_get(hw->slot_id, hw->dev_sd->dtb_sd.queueid,<br />+                &entry_get, 1);<br />+        if (ret == 0) {<br />+            if (unicast_table.entry.hit_flag != 0 && <br />+                    rte_be_to_cpu_16(unicast_table.entry.vfid) != vfid) {<br />+                return -EADDRINUSE;<br />+            }<br />+        }<br />  <br />-        ret = zxdh_np_dtb_table_entry_delete(hw->slot_id,<br />-                    dtb_data->queueid, 1, &entry_get);<br />+        ret = zxdh_np_dtb_table_entry_delete(hw->slot_id, hw->dev_sd->dtb_sd.queueid,<br />+                1, &entry_get);<br />         if (ret) {<br />             PMD_DRV_LOG(ERR, "delete l2_fwd_hash_table failed, code:%d", ret);<br />             return -ret;<br />@@ -366,8 +390,8 @@ zxdh_del_mac_table(struct zxdh_hw *hw, uint16_t vport,<br />             .p_entry_data = (void *)&dtb_hash_entry<br />         };<br />  <br />-        ret = zxdh_np_dtb_table_entry_get(hw->slot_id,<br />-                    dtb_data->queueid, &entry_get, 1);<br />+        ret = zxdh_np_dtb_table_entry_get(hw->slot_id, hw->dev_sd->dtb_sd.queueid,<br />+                &entry_get, 1);<br />         uint8_t index = (vport_num.vfid % 64) / 32;<br />         if (vport_num.vf_flag)<br />             multicast_table.entry.mc_bitmap[index] &=<br />@@ -375,8 +399,8 @@ zxdh_del_mac_table(struct zxdh_hw *hw, uint16_t vport,<br />         else<br />             multicast_table.entry.mc_pf_enable = 0;<br />  <br />-        ret = zxdh_np_dtb_table_entry_write(hw->slot_id,<br />-                    dtb_data->queueid, 1, &entry_get);<br />+        ret = zxdh_np_dtb_table_entry_write(hw->slot_id, hw->dev_sd->dtb_sd.queueid,<br />+                1, &entry_get);<br />         if (ret) {<br />             PMD_DRV_LOG(ERR, "mac_addr_add mc_table failed, code:%d", ret);<br />             return -ret;<br />@@ -395,8 +419,8 @@ zxdh_del_mac_table(struct zxdh_hw *hw, uint16_t vport,<br />                 .p_entry_data = (void *)&dtb_hash_entry<br />             };<br />  <br />-            ret = zxdh_np_dtb_table_entry_get(hw->slot_id, dtb_data->queueid,<br />-                        &entry_get, 1);<br />+            ret = zxdh_np_dtb_table_entry_get(hw->slot_id, hw->dev_sd->dtb_sd.queueid,<br />+                    &entry_get, 1);<br />             if (multicast_table.entry.mc_bitmap[0] == 0 && <br />                 multicast_table.entry.mc_bitmap[1] == 0 && <br />                 multicast_table.entry.mc_pf_enable == 0) {<br />@@ -421,7 +445,7 @@ zxdh_del_mac_table(struct zxdh_hw *hw, uint16_t vport,<br />                 };<br />  <br />                 ret = zxdh_np_dtb_table_entry_delete(hw->slot_id,<br />-                            dtb_data->queueid, 1, &entry_get);<br />+                        hw->dev_sd->dtb_sd.queueid, 1, &entry_get);<br />             }<br />         }<br />     }<br />diff --git a/drivers/net/zxdh/zxdh_tables.h b/drivers/net/zxdh/zxdh_tables.h<br />index f668dad434..7b876d504f 100644<br />--- a/drivers/net/zxdh/zxdh_tables.h<br />+++ b/drivers/net/zxdh/zxdh_tables.h<br />@@ -150,8 +150,9 @@ struct zxdh_panel_table {<br /> }; /* 16B */<br />  <br /> struct zxdh_mac_unicast_key {<br />-    uint16_t rsv;<br />     uint8_t  dmac_addr[6];<br />+    uint16_t sriov_vlan_tpid;<br />+    uint16_t sriov_vlan_id;<br /> };<br />  <br /> struct zxdh_mac_unicast_entry {<br />@@ -218,10 +219,10 @@ int zxdh_get_port_attr(struct zxdh_hw *hw, uint16_t vport,<br />         struct zxdh_port_attr_table *port_attr);<br /> int zxdh_delete_port_attr(struct zxdh_hw *hw, uint16_t vport,<br />         struct zxdh_port_attr_table *port_attr);<br />-int zxdh_set_mac_table(struct zxdh_hw *hw, uint16_t vport,<br />-        struct rte_ether_addr *addr,  uint8_t hash_search_idx);<br />-int zxdh_del_mac_table(struct zxdh_hw *hw, uint16_t vport,<br />-        struct rte_ether_addr *addr,  uint8_t hash_search_idx);<br />+int zxdh_add_mac_table(struct zxdh_hw *hw, uint16_t vport, struct rte_ether_addr *addr,<br />+                uint8_t hash_search_idx, uint16_t srv_tpid, uint16_t srv_vlanid);<br />+int zxdh_del_mac_table(struct zxdh_hw *hw, uint16_t vport, struct rte_ether_addr *addr,<br />+             uint8_t hash_search_idx, uint16_t srv_tpid, uint16_t srv_vlanid);<br /> int zxdh_promisc_table_init(struct rte_eth_dev *dev);<br /> int zxdh_promisc_table_uninit(struct rte_eth_dev *dev);<br /> int zxdh_dev_unicast_table_set(struct zxdh_hw *hw, uint16_t vport, bool enable);<br />--  <br />2.27.0<br />