optimize MAC ops

Signed-off-by: Junlong Wang <wang.junlo...@zte.com.cn>
---
 drivers/net/zxdh/zxdh_ethdev.c     |  41 +++++++++-
 drivers/net/zxdh/zxdh_ethdev.h     |  13 +++-
 drivers/net/zxdh/zxdh_ethdev_ops.c |  59 +++++++++------
 drivers/net/zxdh/zxdh_msg.c        | 118 +++++++++++++++++++++++++++++
 drivers/net/zxdh/zxdh_msg.h        |   7 ++
 drivers/net/zxdh/zxdh_tables.c     |  70 +++++++++++------
 drivers/net/zxdh/zxdh_tables.h     |  11 +--
 7 files changed, 263 insertions(+), 56 deletions(-)

diff --git a/drivers/net/zxdh/zxdh_ethdev.c b/drivers/net/zxdh/zxdh_ethdev.c
index 7efd4fd81c..c430038298 100644
--- a/drivers/net/zxdh/zxdh_ethdev.c
+++ b/drivers/net/zxdh/zxdh_ethdev.c
@@ -1152,8 +1152,8 @@ zxdh_mac_config(struct rte_eth_dev *eth_dev)
        int ret = 0;
 
        if (hw->is_pf) {
-               ret = zxdh_set_mac_table(hw, hw->vport.vport,
-                               &eth_dev->data->mac_addrs[0], 
hw->hash_search_index);
+               ret = zxdh_add_mac_table(hw, hw->vport.vport,
+                               &eth_dev->data->mac_addrs[0], 
hw->hash_search_index, 0, 0);
                if (ret) {
                        PMD_DRV_LOG(ERR, "Failed to add mac: port 0x%x", 
hw->vport.vport);
                        return ret;
@@ -1553,7 +1553,6 @@ zxdh_init_once(struct rte_eth_dev *eth_dev)
        if (!sd->init_done)
                sd->init_done = true;
        sd->dev_refcnt++;
-
 out:
        rte_spinlock_unlock(&sd->lock);
        return ret;
@@ -1640,6 +1639,39 @@ zxdh_queue_res_get(struct rte_eth_dev *eth_dev)
                hw->queue_pool_start = 0;
 }
 
+static int
+zxdh_priv_res_init(struct zxdh_hw *hw)
+{
+       if (hw->is_pf) {
+               hw->vfinfo = rte_zmalloc("vfinfo", ZXDH_MAX_VF * sizeof(struct 
vfinfo), 4);
+               if (hw->vfinfo == NULL) {
+                       PMD_DRV_LOG(ERR, "vfinfo malloc failed");
+                       return -ENOMEM;
+               }
+       } else {
+               hw->vfinfo = NULL;
+       }
+
+       hw->channel_context = rte_zmalloc("zxdh_chnlctx",
+                       sizeof(struct zxdh_chnl_context) * ZXDH_QUEUES_NUM_MAX, 
0);
+       if (hw->channel_context == NULL) {
+               PMD_DRV_LOG(ERR, "Failed to allocate channel_context");
+               return -ENOMEM;
+       }
+       return 0;
+}
+
+static void
+zxdh_priv_res_free(struct zxdh_hw *priv)
+{
+       rte_free(priv->vfinfo);
+       priv->vfinfo = NULL;
+       if (priv->channel_context != NULL) {
+               rte_free(priv->channel_context);
+               priv->channel_context = NULL;
+       }
+}
+
 static int
 zxdh_eth_dev_init(struct rte_eth_dev *eth_dev)
 {
@@ -1715,6 +1747,8 @@ zxdh_eth_dev_init(struct rte_eth_dev *eth_dev)
 
        zxdh_queue_res_get(eth_dev);
        zxdh_msg_cb_reg(hw);
+       if (zxdh_priv_res_init(hw) != 0)
+               goto err_zxdh_init;
        ret = zxdh_configure_intr(eth_dev);
        if (ret != 0)
                goto err_zxdh_init;
@@ -1729,6 +1763,7 @@ zxdh_eth_dev_init(struct rte_eth_dev *eth_dev)
        zxdh_intr_release(eth_dev);
        zxdh_np_uninit(eth_dev);
        zxdh_bar_msg_chan_exit();
+       zxdh_priv_res_free(hw);
        rte_free(eth_dev->data->mac_addrs);
        eth_dev->data->mac_addrs = NULL;
        return ret;
diff --git a/drivers/net/zxdh/zxdh_ethdev.h b/drivers/net/zxdh/zxdh_ethdev.h
index 26fcabb3ec..be026d5b72 100644
--- a/drivers/net/zxdh/zxdh_ethdev.h
+++ b/drivers/net/zxdh/zxdh_ethdev.h
@@ -41,6 +41,7 @@
 
 #define ZXDH_MAX_NAME_LEN               32
 #define ZXDH_SLOT_MAX             256
+#define ZXDH_MAX_VF               256
 
 union zxdh_virport_num {
        uint16_t vport;
@@ -66,6 +67,15 @@ struct zxdh_vlan_offload_cfg {
        uint8_t resv:4;
 };
 
+struct vfinfo {
+       uint16_t vf_idx;
+       uint16_t pcieid;
+       uint16_t vport;
+       uint8_t flag;
+       uint8_t state;
+       struct rte_ether_addr vf_mac[ZXDH_MAX_MAC_ADDRS];
+};
+
 struct zxdh_hw {
        struct rte_eth_dev *eth_dev;
        struct zxdh_pci_common_cfg *common_cfg;
@@ -73,8 +83,9 @@ struct zxdh_hw {
        struct rte_intr_handle *risc_intr;
        struct rte_intr_handle *dtb_intr;
        struct zxdh_virtqueue **vqs;
-       struct zxdh_chnl_context channel_context[ZXDH_QUEUES_NUM_MAX];
+       struct zxdh_chnl_context *channel_context;
        struct zxdh_dev_shared_data *dev_sd;
+       struct vfinfo *vfinfo;
 
        uint64_t bar_addr[ZXDH_NUM_BARS];
        uint64_t host_features;
diff --git a/drivers/net/zxdh/zxdh_ethdev_ops.c 
b/drivers/net/zxdh/zxdh_ethdev_ops.c
index 0c92bd7c05..6e69504c66 100644
--- a/drivers/net/zxdh/zxdh_ethdev_ops.c
+++ b/drivers/net/zxdh/zxdh_ethdev_ops.c
@@ -293,7 +293,8 @@ int zxdh_dev_set_link_down(struct rte_eth_dev *dev)
        return ret;
 }
 
-int zxdh_dev_mac_addr_set(struct rte_eth_dev *dev, struct rte_ether_addr *addr)
+int
+zxdh_dev_mac_addr_set(struct rte_eth_dev *dev, struct rte_ether_addr *addr)
 {
        struct zxdh_hw *hw = (struct zxdh_hw *)dev->data->dev_private;
        struct rte_ether_addr *old_addr = &dev->data->mac_addrs[0];
@@ -304,54 +305,63 @@ int zxdh_dev_mac_addr_set(struct rte_eth_dev *dev, struct 
rte_ether_addr *addr)
                PMD_DRV_LOG(ERR, "mac address is invalid!");
                return -EINVAL;
        }
+       if (rte_is_same_ether_addr(old_addr, addr))
+               return 0;
 
        if (hw->is_pf) {
-               ret = zxdh_del_mac_table(hw, hw->vport.vport, old_addr, 
hw->hash_search_index);
+               ret = zxdh_add_mac_table(hw, hw->vport.vport, addr, 
hw->hash_search_index, 0, 0);
                if (ret) {
+                       if (ret == ZXDH_EEXIST_MAC_FLAG) {
+                               PMD_DRV_LOG(ERR, "pf mac add failed! mac is in 
used, code:%d", ret);
+                               return -EADDRINUSE;
+                       }
                        PMD_DRV_LOG(ERR, "mac_addr_add failed, code:%d", ret);
                        return ret;
                }
-               hw->uc_num--;
+               hw->uc_num++;
 
-               ret = zxdh_set_mac_table(hw, hw->vport.vport, addr, 
hw->hash_search_index);
+               ret = zxdh_del_mac_table(hw, hw->vport.vport, old_addr,
+                       hw->hash_search_index, 0, 0);
                if (ret) {
                        PMD_DRV_LOG(ERR, "mac_addr_add failed, code:%d", ret);
                        return ret;
                }
-               hw->uc_num++;
+               hw->uc_num--;
        } else {
                struct zxdh_mac_filter *mac_filter = 
&msg_info.data.mac_filter_msg;
-
                mac_filter->filter_flag = ZXDH_MAC_UNFILTER;
-               mac_filter->mac_flag = true;
-               memcpy(&mac_filter->mac, old_addr, sizeof(struct 
rte_ether_addr));
-               zxdh_msg_head_build(hw, ZXDH_MAC_DEL, &msg_info);
+               memcpy(&mac_filter->mac, addr, sizeof(struct rte_ether_addr));
+               zxdh_msg_head_build(hw, ZXDH_MAC_ADD, &msg_info);
                ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(msg_info), 
NULL, 0);
                if (ret) {
+                       if (ret == ZXDH_EEXIST_MAC_FLAG) {
+                               PMD_DRV_LOG(ERR, "pf mac add failed! mac is in 
used, code:%d", ret);
+                               return -EADDRINUSE;
+                       }
                        PMD_DRV_LOG(ERR, "Failed to send msg: port 0x%x msg 
type %d",
-                               hw->vport.vport, ZXDH_MAC_DEL);
+                               hw->vport.vport, ZXDH_MAC_ADD);
                        return ret;
                }
-               hw->uc_num--;
-               PMD_DRV_LOG(INFO, "Success to send msg: port 0x%x msg type %d",
-                       hw->vport.vport, ZXDH_MAC_DEL);
+               hw->uc_num++;
 
                mac_filter->filter_flag = ZXDH_MAC_UNFILTER;
-               memcpy(&mac_filter->mac, addr, sizeof(struct rte_ether_addr));
-               zxdh_msg_head_build(hw, ZXDH_MAC_ADD, &msg_info);
+               mac_filter->mac_flag = true;
+               memcpy(&mac_filter->mac, old_addr, sizeof(struct 
rte_ether_addr));
+               zxdh_msg_head_build(hw, ZXDH_MAC_DEL, &msg_info);
                ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(msg_info), 
NULL, 0);
                if (ret) {
                        PMD_DRV_LOG(ERR, "Failed to send msg: port 0x%x msg 
type %d",
-                               hw->vport.vport, ZXDH_MAC_ADD);
+                               hw->vport.vport, ZXDH_MAC_DEL);
                        return ret;
                }
-               hw->uc_num++;
+               hw->uc_num--;
        }
        rte_ether_addr_copy(addr, (struct rte_ether_addr *)hw->mac_addr);
        return ret;
 }
 
-int zxdh_dev_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr 
*mac_addr,
+int
+zxdh_dev_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,
        uint32_t index, uint32_t vmdq __rte_unused)
 {
        struct zxdh_hw *hw = dev->data->dev_private;
@@ -374,12 +384,13 @@ int zxdh_dev_mac_addr_add(struct rte_eth_dev *dev, struct 
rte_ether_addr *mac_ad
        if (hw->is_pf) {
                if (rte_is_unicast_ether_addr(mac_addr)) {
                        if (hw->uc_num < ZXDH_MAX_UC_MAC_ADDRS) {
-                               ret = zxdh_set_mac_table(hw, hw->vport.vport,
-                                               mac_addr, 
hw->hash_search_index);
+                               ret = zxdh_add_mac_table(hw, hw->vport.vport,
+                                                       mac_addr, 
hw->hash_search_index, 0, 0);
                                if (ret) {
                                        PMD_DRV_LOG(ERR, "mac_addr_add failed, 
code:%d", ret);
                                        return ret;
                                }
+                               memcpy(&hw->mac_addr, mac_addr, 6);
                                hw->uc_num++;
                        } else {
                                PMD_DRV_LOG(ERR, "MC_MAC is out of range, 
MAX_MC_MAC:%d",
@@ -388,8 +399,8 @@ int zxdh_dev_mac_addr_add(struct rte_eth_dev *dev, struct 
rte_ether_addr *mac_ad
                        }
                } else {
                        if (hw->mc_num < ZXDH_MAX_MC_MAC_ADDRS) {
-                               ret = zxdh_set_mac_table(hw, hw->vport.vport,
-                                               mac_addr, 
hw->hash_search_index);
+                               ret = zxdh_add_mac_table(hw, hw->vport.vport,
+                                                       mac_addr, 
hw->hash_search_index, 0, 0);
                                if (ret) {
                                        PMD_DRV_LOG(ERR, "mac_addr_add  failed, 
code:%d", ret);
                                        return ret;
@@ -457,7 +468,7 @@ void zxdh_dev_mac_addr_remove(struct rte_eth_dev *dev, 
uint32_t index)
                if (rte_is_unicast_ether_addr(mac_addr)) {
                        if (hw->uc_num <= ZXDH_MAX_UC_MAC_ADDRS) {
                                ret = zxdh_del_mac_table(hw, hw->vport.vport,
-                                               mac_addr, 
hw->hash_search_index);
+                                               mac_addr, 
hw->hash_search_index, 0, 0);
                                if (ret) {
                                        PMD_DRV_LOG(ERR, "mac_addr_del  failed, 
code:%d", ret);
                                        return;
@@ -471,7 +482,7 @@ void zxdh_dev_mac_addr_remove(struct rte_eth_dev *dev, 
uint32_t index)
                } else {
                        if (hw->mc_num <= ZXDH_MAX_MC_MAC_ADDRS) {
                                ret = zxdh_del_mac_table(hw, hw->vport.vport,
-                                                       mac_addr, 
hw->hash_search_index);
+                                                       mac_addr, 
hw->hash_search_index, 0, 0);
                                if (ret) {
                                        PMD_DRV_LOG(ERR, "mac_addr_del  failed, 
code:%d", ret);
                                        return;
diff --git a/drivers/net/zxdh/zxdh_msg.c b/drivers/net/zxdh/zxdh_msg.c
index fbd2315926..a278e080e7 100644
--- a/drivers/net/zxdh/zxdh_msg.c
+++ b/drivers/net/zxdh/zxdh_msg.c
@@ -1260,6 +1260,28 @@ zxdh_vf_port_init(struct zxdh_hw *pf_hw, uint16_t vport, 
void *cfg_data,
        return ret;
 }
 
+static int
+zxdh_mac_clear(struct zxdh_hw *hw, union zxdh_virport_num vport)
+{
+       uint16_t vf_id = vport.vfid;
+       int i;
+       int ret = 0;
+
+       for (i = 0; (i != ZXDH_MAX_MAC_ADDRS); ++i) {
+               if (!rte_is_zero_ether_addr(&hw->vfinfo[vf_id].vf_mac[i])) {
+                       ret = zxdh_del_mac_table(hw, vport.vport,
+                                       &hw->vfinfo[vf_id].vf_mac[i],
+                                       hw->hash_search_index, 0, 0);
+                       if (ret) {
+                               PMD_DRV_LOG(ERR, "vf_del_mac_failed. code:%d", 
ret);
+                               return ret;
+                       }
+                       memset(&hw->vfinfo[vf_id].vf_mac[i], 0, sizeof(struct 
rte_ether_addr));
+               }
+       }
+       return ret;
+}
+
 static int
 zxdh_vf_port_uninit(struct zxdh_hw *pf_hw,
                uint16_t vport, void *cfg_data __rte_unused,
@@ -1267,6 +1289,7 @@ zxdh_vf_port_uninit(struct zxdh_hw *pf_hw,
 {
        char str[ZXDH_MSG_REPLY_BODY_MAX_LEN] = "uninit";
        struct zxdh_port_attr_table port_attr = {0};
+       union zxdh_virport_num vport_num = {.vport = vport};
        int ret = 0;
 
        *res_len =  ZXDH_MSG_REPLYBODY_HEAD;
@@ -1278,6 +1301,12 @@ zxdh_vf_port_uninit(struct zxdh_hw *pf_hw,
                goto proc_end;
        }
 
+       ret = zxdh_mac_clear(pf_hw, vport_num);
+       if (ret) {
+               PMD_DRV_LOG(ERR, "zxdh_mac_clear failed, code:%d", ret);
+               goto proc_end;
+       }
+
        *res_len += strlen(str);
        rte_memcpy(&res_info->reply_data, str, strlen(str) + 1);
        res_info->flag = ZXDH_REPS_SUCC;
@@ -1290,10 +1319,99 @@ zxdh_vf_port_uninit(struct zxdh_hw *pf_hw,
        return ret;
 }
 
+static int
+zxdh_add_vf_mac_table(struct zxdh_hw *hw, uint16_t vport, void *cfg_data,
+               struct zxdh_msg_reply_body *reply_body, uint16_t *reply_len)
+{
+       char str[ZXDH_MSG_REPLY_BODY_MAX_LEN] = "add mac";
+       union zxdh_virport_num port = {0};
+       struct zxdh_mac_filter *mac_filter = (struct zxdh_mac_filter *)cfg_data;
+       struct rte_ether_addr *addr = &mac_filter->mac;
+       int i = 0, ret = 0;
+       uint16_t vf_id = port.vfid;
+       port.vport = vport;
+
+       for (i = 0; i < ZXDH_MAX_MAC_ADDRS; i++)
+               if (rte_is_same_ether_addr(&hw->vfinfo[vf_id].vf_mac[i], addr))
+                       goto success;
+
+       ret = zxdh_add_mac_table(hw, vport, addr, hw->hash_search_index, 0, 0);
+       if (ret == -EADDRINUSE) {
+               reply_body->mac_reply_msg.mac_flag = ZXDH_EEXIST_MAC_FLAG;
+               PMD_DRV_LOG(ERR, "vf vport 0x%x set mac ret 0x%x failed. mac is 
in used.",
+                               port.vport, ret);
+               goto failure;
+       }
+       if (ret) {
+               sprintf(str, "[PF GET MSG FROM VF]--VF add mac failed. 
code:%d\n", ret);
+               PMD_DRV_LOG(ERR, " %s", str);
+               goto failure;
+       }
+       for (i = 0; i < ZXDH_MAX_MAC_ADDRS; i++) {
+               if (rte_is_zero_ether_addr(&hw->vfinfo[vf_id].vf_mac[i])) {
+                       memcpy(&hw->vfinfo[vf_id].vf_mac[i], addr, 6);
+                       break;
+               }
+       }
+
+success:
+       sprintf(str, " vport 0x%x set mac ret 0x%x\n", port.vport, ret);
+       *reply_len =  strlen(str) + ZXDH_MSG_REPLYBODY_HEAD;
+       rte_memcpy(&reply_body->reply_data, str, strlen(str) + 1);
+       reply_body->flag = ZXDH_REPS_SUCC;
+       PMD_DRV_LOG(DEBUG, " reply len %d", *reply_len);
+       return ret;
+
+failure:
+       *reply_len = strlen(str) + ZXDH_MSG_REPLYBODY_HEAD;
+       reply_body->flag = ZXDH_REPS_FAIL;
+       return ret;
+}
+
+static int
+zxdh_del_vf_mac_table(struct zxdh_hw *hw, uint16_t vport, void *cfg_data,
+       struct zxdh_msg_reply_body *res_info, uint16_t *res_len)
+{
+       int ret, i = 0;
+       struct zxdh_mac_filter *mac_filter = (struct zxdh_mac_filter *)cfg_data;
+       union zxdh_virport_num  port = (union zxdh_virport_num)vport;
+       char str[ZXDH_MSG_REPLY_BODY_MAX_LEN] = "del mac";
+       uint16_t  vf_id = port.vfid;
+
+       PMD_DRV_LOG(DEBUG, "[PF GET MSG FROM VF]--vf mac to del.");
+       ret = zxdh_del_mac_table(hw, vport, &mac_filter->mac, 
hw->hash_search_index, 0, 0);
+       if (ret == -EADDRINUSE)
+               ret = 0;
+
+       if (ret) {
+               sprintf(str, "[PF GET MSG FROM VF]--VF del mac failed. 
code:%d\n", ret);
+               PMD_DRV_LOG(ERR, "%s", str);
+               goto proc_end;
+       }
+
+       for (i = 0; i < ZXDH_MAX_MAC_ADDRS; i++) {
+               if (rte_is_same_ether_addr(&hw->vfinfo[vf_id].vf_mac[i], 
&mac_filter->mac))
+                       memset(&hw->vfinfo[vf_id].vf_mac[i], 0, sizeof(struct 
rte_ether_addr));
+       }
+
+       sprintf(str, "vport 0x%x del mac ret 0x%x\n", port.vport, ret);
+       *res_len =  strlen(str) + ZXDH_MSG_REPLYBODY_HEAD;
+       rte_memcpy(&res_info->reply_data, str, strlen(str) + 1);
+       res_info->flag = ZXDH_REPS_SUCC;
+       return ret;
+
+proc_end:
+       *res_len = strlen(str) + ZXDH_MSG_REPLYBODY_HEAD;
+       res_info->flag = ZXDH_REPS_FAIL;
+       return ret;
+}
+
 static const zxdh_msg_process_callback zxdh_proc_cb[] = {
        [ZXDH_NULL] = NULL,
        [ZXDH_VF_PORT_INIT] = zxdh_vf_port_init,
        [ZXDH_VF_PORT_UNINIT] = zxdh_vf_port_uninit,
+       [ZXDH_MAC_ADD] = zxdh_add_vf_mac_table,
+       [ZXDH_MAC_DEL] = zxdh_del_vf_mac_table,
 };
 
 static inline int
diff --git a/drivers/net/zxdh/zxdh_msg.h b/drivers/net/zxdh/zxdh_msg.h
index 7af20520c3..36364eb1fb 100644
--- a/drivers/net/zxdh/zxdh_msg.h
+++ b/drivers/net/zxdh/zxdh_msg.h
@@ -59,6 +59,8 @@
 #define ZXDH_VLAN_STRIP_MSG_TYPE   0
 #define ZXDH_QINQ_STRIP_MSG_TYPE   1
 
+#define ZXDH_EEXIST_MAC_FLAG       0xFD
+
 enum ZXDH_DRIVER_TYPE {
        ZXDH_MSG_CHAN_END_MPF = 0,
        ZXDH_MSG_CHAN_END_PF,
@@ -330,6 +332,10 @@ struct zxdh_rss_hf {
        uint32_t rss_hf;
 };
 
+struct zxdh_mac_reply_msg {
+       uint8_t mac_flag;
+};
+
 struct zxdh_msg_reply_body {
        enum zxdh_reps_flag flag;
        union {
@@ -339,6 +345,7 @@ struct zxdh_msg_reply_body {
                struct zxdh_rss_reta rss_reta;
                struct zxdh_rss_hf rss_hf;
                struct zxdh_hw_vqm_stats vqm_stats;
+               struct zxdh_mac_reply_msg mac_reply_msg;
        };
 };
 
diff --git a/drivers/net/zxdh/zxdh_tables.c b/drivers/net/zxdh/zxdh_tables.c
index a5d598d022..bfc240a051 100644
--- a/drivers/net/zxdh/zxdh_tables.c
+++ b/drivers/net/zxdh/zxdh_tables.c
@@ -232,20 +232,20 @@ zxdh_delete_port_attr(struct zxdh_hw *hw, uint16_t vport,
 }
 
 int
-zxdh_set_mac_table(struct zxdh_hw *hw, uint16_t vport,
-               struct rte_ether_addr *addr, uint8_t hash_search_idx)
+zxdh_add_mac_table(struct zxdh_hw *hw, uint16_t vport, struct rte_ether_addr 
*addr,
+               uint8_t hash_search_idx, uint16_t srv_tpid, uint16_t srv_vlanid)
 {
-       struct zxdh_dtb_shared_data *dtb_data = &hw->dev_sd->dtb_sd;
        struct zxdh_mac_unicast_table unicast_table = {0};
        struct zxdh_mac_multicast_table multicast_table = {0};
        union zxdh_virport_num vport_num = (union zxdh_virport_num)vport;
        uint32_t ret;
        uint16_t group_id = 0;
+       uint16_t vfid = vport_num.vfid;
 
        if (rte_is_unicast_ether_addr(addr)) {
                rte_memcpy(unicast_table.key.dmac_addr, addr, sizeof(struct 
rte_ether_addr));
-               unicast_table.entry.hit_flag = 0;
-               unicast_table.entry.vfid = vport_num.vfid;
+               unicast_table.key.sriov_vlan_tpid = srv_tpid;
+               unicast_table.key.sriov_vlan_id = srv_vlanid;
 
                ZXDH_DTB_HASH_ENTRY_INFO_T dtb_hash_entry = {
                        .p_actu_key = (uint8_t *)&unicast_table.key,
@@ -256,8 +256,24 @@ zxdh_set_mac_table(struct zxdh_hw *hw, uint16_t vport,
                        .p_entry_data = (void *)&dtb_hash_entry
                };
 
+               ret = zxdh_np_dtb_table_entry_get(hw->slot_id, 
hw->dev_sd->dtb_sd.queueid,
+                               &entry_get, 1);
+               if (ret == 0) {
+                       if (unicast_table.entry.hit_flag != 0 &&
+                                       
rte_be_to_cpu_16(unicast_table.entry.vfid) != vfid) {
+                               return -EADDRINUSE;
+                       } else if (unicast_table.entry.hit_flag != 0 &&
+                                       
rte_be_to_cpu_16(unicast_table.entry.vfid) == vfid) {
+                               PMD_DRV_LOG(DEBUG, "vfid:%d, equals to itself 
mac, ret:%d",
+                                       vfid, ret);
+                               return 0;
+                       }
+               }
+
+               unicast_table.entry.vfid = rte_cpu_to_be_16(vfid);
+               unicast_table.entry.hit_flag = 1;
                ret = zxdh_np_dtb_table_entry_write(hw->slot_id,
-                                       dtb_data->queueid, 1, &entry_get);
+                                       hw->dev_sd->dtb_sd.queueid, 1, 
&entry_get);
                if (ret) {
                        PMD_DRV_LOG(ERR, "Insert mac_table failed");
                        return -ret;
@@ -277,7 +293,7 @@ zxdh_set_mac_table(struct zxdh_hw *hw, uint16_t vport,
                                .p_entry_data = (void *)&dtb_hash_entry
                        };
 
-                       ret = zxdh_np_dtb_table_entry_get(hw->slot_id, 
dtb_data->queueid,
+                       ret = zxdh_np_dtb_table_entry_get(hw->slot_id, 
hw->dev_sd->dtb_sd.queueid,
                                        &entry_get, 1);
                        uint8_t index = (vport_num.vfid % 64) / 32;
                        if (ret == 0) {
@@ -308,8 +324,7 @@ zxdh_set_mac_table(struct zxdh_hw *hw, uint16_t vport,
                                                
multicast_table.entry.mc_pf_enable = false;
                                }
                        }
-
-                       ret = zxdh_np_dtb_table_entry_write(hw->slot_id, 
dtb_data->queueid,
+                       ret = zxdh_np_dtb_table_entry_write(hw->slot_id, 
hw->dev_sd->dtb_sd.queueid,
                                                1, &entry_get);
                        if (ret) {
                                PMD_DRV_LOG(ERR, "add mac_table failed, 
code:%d", ret);
@@ -321,20 +336,21 @@ zxdh_set_mac_table(struct zxdh_hw *hw, uint16_t vport,
 }
 
 int
-zxdh_del_mac_table(struct zxdh_hw *hw, uint16_t vport,
-               struct rte_ether_addr *addr, uint8_t hash_search_idx)
+zxdh_del_mac_table(struct zxdh_hw *hw, uint16_t vport, struct rte_ether_addr 
*addr,
+               uint8_t hash_search_idx, uint16_t srv_tpid, uint16_t srv_vlanid)
 {
-       struct zxdh_dtb_shared_data *dtb_data = &hw->dev_sd->dtb_sd;
        struct zxdh_mac_unicast_table unicast_table = {0};
        struct zxdh_mac_multicast_table multicast_table = {0};
        union zxdh_virport_num vport_num = (union zxdh_virport_num)vport;
        uint32_t ret, del_flag = 0;
        uint16_t group_id = 0;
+       union zxdh_virport_num port = (union zxdh_virport_num)vport;
+       uint16_t vfid = zxdh_vport_to_vfid(port);
 
        if (rte_is_unicast_ether_addr(addr)) {
                rte_memcpy(unicast_table.key.dmac_addr, addr, sizeof(struct 
rte_ether_addr));
-               unicast_table.entry.hit_flag = 0;
-               unicast_table.entry.vfid = vport_num.vfid;
+               unicast_table.key.sriov_vlan_id = srv_vlanid;
+               unicast_table.key.sriov_vlan_tpid = srv_tpid;
 
                ZXDH_DTB_HASH_ENTRY_INFO_T dtb_hash_entry = {
                        .p_actu_key = (uint8_t *)&unicast_table.key,
@@ -345,9 +361,17 @@ zxdh_del_mac_table(struct zxdh_hw *hw, uint16_t vport,
                        .sdt_no = ZXDH_MAC_HASH_INDEX(hash_search_idx),
                        .p_entry_data = (void *)&dtb_hash_entry
                };
+               ret = zxdh_np_dtb_table_entry_get(hw->slot_id, 
hw->dev_sd->dtb_sd.queueid,
+                               &entry_get, 1);
+               if (ret == 0) {
+                       if (unicast_table.entry.hit_flag != 0 &&
+                                       
rte_be_to_cpu_16(unicast_table.entry.vfid) != vfid) {
+                               return -EADDRINUSE;
+                       }
+               }
 
-               ret = zxdh_np_dtb_table_entry_delete(hw->slot_id,
-                                       dtb_data->queueid, 1, &entry_get);
+               ret = zxdh_np_dtb_table_entry_delete(hw->slot_id, 
hw->dev_sd->dtb_sd.queueid,
+                               1, &entry_get);
                if (ret) {
                        PMD_DRV_LOG(ERR, "delete l2_fwd_hash_table failed, 
code:%d", ret);
                        return -ret;
@@ -366,8 +390,8 @@ zxdh_del_mac_table(struct zxdh_hw *hw, uint16_t vport,
                        .p_entry_data = (void *)&dtb_hash_entry
                };
 
-               ret = zxdh_np_dtb_table_entry_get(hw->slot_id,
-                                       dtb_data->queueid, &entry_get, 1);
+               ret = zxdh_np_dtb_table_entry_get(hw->slot_id, 
hw->dev_sd->dtb_sd.queueid,
+                               &entry_get, 1);
                uint8_t index = (vport_num.vfid % 64) / 32;
                if (vport_num.vf_flag)
                        multicast_table.entry.mc_bitmap[index] &=
@@ -375,8 +399,8 @@ zxdh_del_mac_table(struct zxdh_hw *hw, uint16_t vport,
                else
                        multicast_table.entry.mc_pf_enable = 0;
 
-               ret = zxdh_np_dtb_table_entry_write(hw->slot_id,
-                                       dtb_data->queueid, 1, &entry_get);
+               ret = zxdh_np_dtb_table_entry_write(hw->slot_id, 
hw->dev_sd->dtb_sd.queueid,
+                               1, &entry_get);
                if (ret) {
                        PMD_DRV_LOG(ERR, "mac_addr_add mc_table failed, 
code:%d", ret);
                        return -ret;
@@ -395,8 +419,8 @@ zxdh_del_mac_table(struct zxdh_hw *hw, uint16_t vport,
                                .p_entry_data = (void *)&dtb_hash_entry
                        };
 
-                       ret = zxdh_np_dtb_table_entry_get(hw->slot_id, 
dtb_data->queueid,
-                                               &entry_get, 1);
+                       ret = zxdh_np_dtb_table_entry_get(hw->slot_id, 
hw->dev_sd->dtb_sd.queueid,
+                                       &entry_get, 1);
                        if (multicast_table.entry.mc_bitmap[0] == 0 &&
                                multicast_table.entry.mc_bitmap[1] == 0 &&
                                multicast_table.entry.mc_pf_enable == 0) {
@@ -421,7 +445,7 @@ zxdh_del_mac_table(struct zxdh_hw *hw, uint16_t vport,
                                };
 
                                ret = 
zxdh_np_dtb_table_entry_delete(hw->slot_id,
-                                                       dtb_data->queueid, 1, 
&entry_get);
+                                               hw->dev_sd->dtb_sd.queueid, 1, 
&entry_get);
                        }
                }
        }
diff --git a/drivers/net/zxdh/zxdh_tables.h b/drivers/net/zxdh/zxdh_tables.h
index b8cc9df5c8..de30474210 100644
--- a/drivers/net/zxdh/zxdh_tables.h
+++ b/drivers/net/zxdh/zxdh_tables.h
@@ -164,8 +164,9 @@ struct zxdh_panel_table {
 }; /* 16B */
 
 struct zxdh_mac_unicast_key {
-       uint16_t rsv;
        uint8_t  dmac_addr[6];
+       uint16_t sriov_vlan_tpid;
+       uint16_t sriov_vlan_id;
 };
 
 struct zxdh_mac_unicast_entry {
@@ -232,10 +233,10 @@ int zxdh_get_port_attr(struct zxdh_hw *hw, uint16_t vport,
                struct zxdh_port_attr_table *port_attr);
 int zxdh_delete_port_attr(struct zxdh_hw *hw, uint16_t vport,
                struct zxdh_port_attr_table *port_attr);
-int zxdh_set_mac_table(struct zxdh_hw *hw, uint16_t vport,
-               struct rte_ether_addr *addr,  uint8_t hash_search_idx);
-int zxdh_del_mac_table(struct zxdh_hw *hw, uint16_t vport,
-               struct rte_ether_addr *addr,  uint8_t hash_search_idx);
+int zxdh_add_mac_table(struct zxdh_hw *hw, uint16_t vport, struct 
rte_ether_addr *addr,
+                               uint8_t hash_search_idx, uint16_t srv_tpid, 
uint16_t srv_vlanid);
+int zxdh_del_mac_table(struct zxdh_hw *hw, uint16_t vport, struct 
rte_ether_addr *addr,
+                        uint8_t hash_search_idx, uint16_t srv_tpid, uint16_t 
srv_vlanid);
 int zxdh_promisc_table_init(struct rte_eth_dev *dev);
 int zxdh_promisc_table_uninit(struct rte_eth_dev *dev);
 int zxdh_dev_unicast_table_set(struct zxdh_hw *hw, uint16_t vport, bool 
enable);
-- 
2.27.0

Reply via email to