provided mac set/add/remove ops.<br /> <br />Signed-off-by: Junlong Wang <wang.junlong1@zte.com.cn> <br />---<br /> doc/guides/nics/features/zxdh.ini  |   2 +<br /> doc/guides/nics/zxdh.rst           |   2 +<br /> drivers/net/zxdh/zxdh_common.c     |  24 +++<br /> drivers/net/zxdh/zxdh_common.h     |   1 +<br /> drivers/net/zxdh/zxdh_ethdev.c     |  33 ++++-<br /> drivers/net/zxdh/zxdh_ethdev.h     |   3 +<br /> drivers/net/zxdh/zxdh_ethdev_ops.c | 231 +++++++++++++++++++++++++++++<br /> drivers/net/zxdh/zxdh_ethdev_ops.h |   4 +<br /> drivers/net/zxdh/zxdh_msg.h        |  12 ++<br /> drivers/net/zxdh/zxdh_np.h         |   5 +<br /> drivers/net/zxdh/zxdh_tables.c     | 197 ++++++++++++++++++++++++<br /> drivers/net/zxdh/zxdh_tables.h     |  36 +++++<br /> 12 files changed, 548 insertions(+), 2 deletions(-)<br /> <br />diff --git a/doc/guides/nics/features/zxdh.ini b/doc/guides/nics/features/zxdh.ini<br />index 7da3aaced1..dc09fe3453 100644<br />--- a/doc/guides/nics/features/zxdh.ini<br />+++ b/doc/guides/nics/features/zxdh.ini<br />@@ -12,3 +12,5 @@ Multiprocess aware   = Y<br /> Scattered Rx         = Y<br /> Link status          = Y<br /> Link status event    = Y<br />+Unicast MAC filter   = Y<br />+Multicast MAC filter = Y<br />diff --git a/doc/guides/nics/zxdh.rst b/doc/guides/nics/zxdh.rst<br />index fdbc3b3923..e0b0776aca 100644<br />--- a/doc/guides/nics/zxdh.rst<br />+++ b/doc/guides/nics/zxdh.rst<br />@@ -24,6 +24,8 @@ Features of the ZXDH PMD are:<br /> - Link Auto-negotiation<br /> - Link state information<br /> - Set Link down or up<br />+- Unicast MAC filter<br />+- Multicast MAC filter<br />  <br />  <br /> Driver compilation and testing<br />diff --git a/drivers/net/zxdh/zxdh_common.c b/drivers/net/zxdh/zxdh_common.c<br />index 72c0ed65cc..f70c615d2f 100644<br />--- a/drivers/net/zxdh/zxdh_common.c<br />+++ b/drivers/net/zxdh/zxdh_common.c<br />@@ -256,6 +256,30 @@ zxdh_panelid_get(struct rte_eth_dev *dev, uint8_t *panelid)<br />     return ret;<br /> }<br />  <br />+static int<br />+zxdh_get_res_hash_id(struct zxdh_res_para *in, uint8_t *hash_id)<br />+{<br />+    uint8_t reps = 0;<br />+    uint16_t reps_len = 0;<br />+<br />+    if (zxdh_get_res_info(in, ZXDH_TBL_FIELD_HASHID, &reps, &reps_len) != ZXDH_BAR_MSG_OK)<br />+        return -1;<br />+<br />+    *hash_id = reps;<br />+    return ZXDH_BAR_MSG_OK;<br />+}<br />+<br />+int32_t<br />+zxdh_hashidx_get(struct rte_eth_dev *dev, uint8_t *hash_idx)<br />+{<br />+    struct zxdh_res_para param;<br />+<br />+    zxdh_fill_res_para(dev, &param);<br />+    int32_t ret = zxdh_get_res_hash_id(&param, hash_idx);<br />+<br />+    return ret;<br />+}<br />+<br /> uint32_t<br /> zxdh_read_bar_reg(struct rte_eth_dev *dev, uint32_t bar, uint32_t reg)<br /> {<br />diff --git a/drivers/net/zxdh/zxdh_common.h b/drivers/net/zxdh/zxdh_common.h<br />index 72c29e1522..826f1fb95d 100644<br />--- a/drivers/net/zxdh/zxdh_common.h<br />+++ b/drivers/net/zxdh/zxdh_common.h<br />@@ -22,6 +22,7 @@ struct zxdh_res_para {<br />  <br /> int32_t zxdh_phyport_get(struct rte_eth_dev *dev, uint8_t *phyport);<br /> int32_t zxdh_panelid_get(struct rte_eth_dev *dev, uint8_t *pannelid);<br />+int32_t zxdh_hashidx_get(struct rte_eth_dev *dev, uint8_t *hash_idx);<br /> uint32_t zxdh_read_bar_reg(struct rte_eth_dev *dev, uint32_t bar, uint32_t reg);<br /> void zxdh_write_bar_reg(struct rte_eth_dev *dev, uint32_t bar, uint32_t reg, uint32_t val);<br /> void zxdh_release_lock(struct zxdh_hw *hw);<br />diff --git a/drivers/net/zxdh/zxdh_ethdev.c b/drivers/net/zxdh/zxdh_ethdev.c<br />index 4fe5d8c23b..3da51cda14 100644<br />--- a/drivers/net/zxdh/zxdh_ethdev.c<br />+++ b/drivers/net/zxdh/zxdh_ethdev.c<br />@@ -992,6 +992,23 @@ zxdh_set_rxtx_funcs(struct rte_eth_dev *eth_dev)<br />     return 0;<br /> }<br />  <br />+static int<br />+zxdh_mac_config(struct rte_eth_dev *eth_dev)<br />+{<br />+    struct zxdh_hw *hw = eth_dev->data->dev_private;<br />+    int ret = 0;<br />+<br />+    if (hw->is_pf) {<br />+        ret = zxdh_set_mac_table(hw->vport.vport,<br />+                &eth_dev->data->mac_addrs[0], hw->hash_search_index);<br />+        if (ret) {<br />+            PMD_DRV_LOG(ERR, "Failed to add mac: port 0x%x", hw->vport.vport);<br />+            return ret;<br />+        }<br />+    }<br />+    return ret;<br />+}<br />+<br /> static int<br /> zxdh_dev_start(struct rte_eth_dev *dev)<br /> {<br />@@ -1030,6 +1047,10 @@ zxdh_dev_start(struct rte_eth_dev *dev)<br />  <br />     zxdh_dev_set_link_up(dev);<br />  <br />+    ret = zxdh_mac_config(hw->eth_dev);<br />+    if (ret)<br />+        PMD_DRV_LOG(ERR, " mac config failed");<br />+<br />     for (i = 0; i < dev->data->nb_rx_queues; i++)<br />         dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED;<br />     for (i = 0; i < dev->data->nb_tx_queues; i++)<br />@@ -1052,6 +1073,9 @@ static const struct eth_dev_ops zxdh_eth_dev_ops = {<br />     .link_update             = zxdh_dev_link_update,<br />     .dev_set_link_up         = zxdh_dev_set_link_up,<br />     .dev_set_link_down         = zxdh_dev_set_link_down,<br />+    .mac_addr_add             = zxdh_dev_mac_addr_add,<br />+    .mac_addr_remove         = zxdh_dev_mac_addr_remove,<br />+    .mac_addr_set             = zxdh_dev_mac_addr_set,<br /> };<br />  <br /> static int32_t<br />@@ -1093,15 +1117,20 @@ zxdh_agent_comm(struct rte_eth_dev *eth_dev, struct zxdh_hw *hw)<br />         PMD_DRV_LOG(ERR, "Failed to get phyport");<br />         return -1;<br />     }<br />-    PMD_DRV_LOG(INFO, "Get phyport success: 0x%x", hw->phyport);<br />+    PMD_DRV_LOG(DEBUG, "Get phyport success: 0x%x", hw->phyport);<br />  <br />     hw->vfid = zxdh_vport_to_vfid(hw->vport);<br />  <br />+    if (zxdh_hashidx_get(eth_dev, &hw->hash_search_index) != 0) {<br />+        PMD_DRV_LOG(ERR, "Failed to get hash idx");<br />+        return -1;<br />+    }<br />+<br />     if (zxdh_panelid_get(eth_dev, &hw->panel_id) != 0) {<br />         PMD_DRV_LOG(ERR, "Failed to get panel_id");<br />         return -1;<br />     }<br />-    PMD_DRV_LOG(INFO, "Get panel id success: 0x%x", hw->panel_id);<br />+    PMD_DRV_LOG(DEBUG, "Get panel id success: 0x%x", hw->panel_id);<br />  <br />     return 0;<br /> }<br />diff --git a/drivers/net/zxdh/zxdh_ethdev.h b/drivers/net/zxdh/zxdh_ethdev.h<br />index c0b719062c..5b95cb1c2a 100644<br />--- a/drivers/net/zxdh/zxdh_ethdev.h<br />+++ b/drivers/net/zxdh/zxdh_ethdev.h<br />@@ -80,6 +80,8 @@ struct zxdh_hw {<br />     uint16_t port_id;<br />     uint16_t vfid;<br />     uint16_t queue_num;<br />+    uint16_t mc_num;<br />+    uint16_t uc_num;<br />  <br />     uint8_t *isr;<br />     uint8_t weak_barriers;<br />@@ -92,6 +94,7 @@ struct zxdh_hw {<br />     uint8_t msg_chan_init;<br />     uint8_t phyport;<br />     uint8_t panel_id;<br />+    uint8_t hash_search_index;<br />     uint8_t has_tx_offload;<br />     uint8_t has_rx_offload;<br />     uint8_t admin_status;<br />diff --git a/drivers/net/zxdh/zxdh_ethdev_ops.c b/drivers/net/zxdh/zxdh_ethdev_ops.c<br />index 5a0af98cc0..35e37483e3 100644<br />--- a/drivers/net/zxdh/zxdh_ethdev_ops.c<br />+++ b/drivers/net/zxdh/zxdh_ethdev_ops.c<br />@@ -164,3 +164,234 @@ int zxdh_dev_set_link_down(struct rte_eth_dev *dev)<br />         PMD_DRV_LOG(ERR, "Set link down failed");<br />     return ret;<br /> }<br />+<br />+int 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 />+    struct zxdh_msg_info msg_info = {0};<br />+    uint16_t ret = 0;<br />+<br />+    if (!rte_is_valid_assigned_ether_addr(addr)) {<br />+        PMD_DRV_LOG(ERR, "mac address is invalid!");<br />+        return -EINVAL;<br />+    }<br />+<br />+    if (hw->is_pf) {<br />+        ret = zxdh_del_mac_table(hw->vport.vport, old_addr, hw->hash_search_index);<br />+        if (ret) {<br />+            PMD_DRV_LOG(ERR, "mac_addr_add failed, code:%d", ret);<br />+            return ret;<br />+        }<br />+        hw->uc_num--;<br />+<br />+        ret = zxdh_set_mac_table(hw->vport.vport, addr, hw->hash_search_index);<br />+        if (ret) {<br />+            PMD_DRV_LOG(ERR, "mac_addr_add failed, code:%d", ret);<br />+            return ret;<br />+        }<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 />+        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_DEL);<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 />+<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 />+        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 />+            return ret;<br />+        }<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 />+    uint32_t index, uint32_t vmdq __rte_unused)<br />+{<br />+    struct zxdh_hw *hw = dev->data->dev_private;<br />+    struct zxdh_msg_info msg_info = {0};<br />+    uint16_t i, ret;<br />+<br />+    if (index >= ZXDH_MAX_MAC_ADDRS) {<br />+        PMD_DRV_LOG(ERR, "Add mac index (%u) is out of range", index);<br />+        return -EINVAL;<br />+    }<br />+<br />+    for (i = 0; (i != ZXDH_MAX_MAC_ADDRS); ++i) {<br />+        if (memcmp(&dev->data->mac_addrs[i], mac_addr, sizeof(*mac_addr)))<br />+            continue;<br />+<br />+        PMD_DRV_LOG(INFO, "MAC address already configured");<br />+        return -EADDRINUSE;<br />+    }<br />+<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->vport.vport,<br />+                            mac_addr, hw->hash_search_index);<br />+                if (ret) {<br />+                    PMD_DRV_LOG(ERR, "mac_addr_add failed, code:%d", ret);<br />+                    return ret;<br />+                }<br />+                hw->uc_num++;<br />+            } else {<br />+                PMD_DRV_LOG(ERR, "MC_MAC is out of range, MAX_MC_MAC:%d",<br />+                        ZXDH_MAX_MC_MAC_ADDRS);<br />+                return -EINVAL;<br />+            }<br />+        } else {<br />+            if (hw->mc_num < ZXDH_MAX_MC_MAC_ADDRS) {<br />+                ret = zxdh_set_mac_table(hw->vport.vport,<br />+                            mac_addr, hw->hash_search_index);<br />+                if (ret) {<br />+                    PMD_DRV_LOG(ERR, "mac_addr_add  failed, code:%d", ret);<br />+                    return ret;<br />+                }<br />+                hw->mc_num++;<br />+            } else {<br />+                PMD_DRV_LOG(ERR, "MC_MAC is out of range, MAX_MC_MAC:%d",<br />+                        ZXDH_MAX_MC_MAC_ADDRS);<br />+                return -EINVAL;<br />+            }<br />+        }<br />+    } else {<br />+        struct zxdh_mac_filter *mac_filter = &msg_info.data.mac_filter_msg;<br />+<br />+        mac_filter->filter_flag = ZXDH_MAC_FILTER;<br />+        rte_memcpy(&mac_filter->mac, mac_addr, sizeof(struct rte_ether_addr));<br />+        zxdh_msg_head_build(hw, ZXDH_MAC_ADD, &msg_info);<br />+        if (rte_is_unicast_ether_addr(mac_addr)) {<br />+            if (hw->uc_num < ZXDH_MAX_UC_MAC_ADDRS) {<br />+                ret = zxdh_vf_send_msg_to_pf(dev, &msg_info,<br />+                            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 />+                    return ret;<br />+                }<br />+                hw->uc_num++;<br />+            } else {<br />+                PMD_DRV_LOG(ERR, "MC_MAC is out of range, MAX_MC_MAC:%d",<br />+                        ZXDH_MAX_MC_MAC_ADDRS);<br />+                return -EINVAL;<br />+            }<br />+        } else {<br />+            if (hw->mc_num < ZXDH_MAX_MC_MAC_ADDRS) {<br />+                ret = zxdh_vf_send_msg_to_pf(dev, &msg_info,<br />+                            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 />+                    return ret;<br />+                }<br />+                hw->mc_num++;<br />+            } else {<br />+                PMD_DRV_LOG(ERR, "MC_MAC is out of range, MAX_MC_MAC:%d",<br />+                        ZXDH_MAX_MC_MAC_ADDRS);<br />+                return -EINVAL;<br />+            }<br />+        }<br />+    }<br />+    dev->data->mac_addrs[index] = *mac_addr;<br />+    return 0;<br />+}<br />+<br />+void zxdh_dev_mac_addr_remove(struct rte_eth_dev *dev __rte_unused, uint32_t index __rte_unused)<br />+{<br />+    struct zxdh_hw *hw    = dev->data->dev_private;<br />+    struct zxdh_msg_info msg_info = {0};<br />+    struct rte_ether_addr *mac_addr = &dev->data->mac_addrs[index];<br />+    uint16_t ret = 0;<br />+<br />+    if (index >= ZXDH_MAX_MAC_ADDRS)<br />+        return;<br />+<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_del_mac_table(hw->vport.vport,<br />+                        mac_addr, hw->hash_search_index);<br />+                if (ret) {<br />+                    PMD_DRV_LOG(ERR, "mac_addr_del  failed, code:%d", ret);<br />+                    return;<br />+                }<br />+                hw->uc_num--;<br />+            } else {<br />+                PMD_DRV_LOG(ERR, "MC_MAC is out of range, MAX_MC_MAC:%d",<br />+                        ZXDH_MAX_MC_MAC_ADDRS);<br />+                return;<br />+            }<br />+        } else {<br />+            if (hw->mc_num <= ZXDH_MAX_MC_MAC_ADDRS) {<br />+                ret = zxdh_del_mac_table(hw->vport.vport,<br />+                            mac_addr, hw->hash_search_index);<br />+                if (ret) {<br />+                    PMD_DRV_LOG(ERR, "mac_addr_del  failed, code:%d", ret);<br />+                    return;<br />+                }<br />+                hw->mc_num--;<br />+            } else {<br />+                PMD_DRV_LOG(ERR, "MC_MAC is out of range, MAX_MC_MAC:%d",<br />+                        ZXDH_MAX_MC_MAC_ADDRS);<br />+                return;<br />+            }<br />+        }<br />+    } else {<br />+        struct zxdh_mac_filter *mac_filter = &msg_info.data.mac_filter_msg;<br />+<br />+        mac_filter->filter_flag = ZXDH_MAC_FILTER;<br />+        rte_memcpy(&mac_filter->mac, mac_addr, sizeof(struct rte_ether_addr));<br />+        zxdh_msg_head_build(hw, ZXDH_MAC_DEL, &msg_info);<br />+        if (rte_is_unicast_ether_addr(mac_addr)) {<br />+            if (hw->uc_num <= ZXDH_MAX_UC_MAC_ADDRS) {<br />+                ret = zxdh_vf_send_msg_to_pf(dev, &msg_info,<br />+                            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_DEL);<br />+                    return;<br />+                }<br />+                hw->uc_num--;<br />+            } else {<br />+                PMD_DRV_LOG(ERR, "MC_MAC is out of range, MAX_MC_MAC:%d",<br />+                        ZXDH_MAX_MC_MAC_ADDRS);<br />+                return;<br />+            }<br />+        } else {<br />+            if (hw->mc_num <= ZXDH_MAX_MC_MAC_ADDRS) {<br />+                ret = zxdh_vf_send_msg_to_pf(dev, &msg_info,<br />+                            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_DEL);<br />+                    return;<br />+                }<br />+                hw->mc_num--;<br />+            } else {<br />+                PMD_DRV_LOG(ERR, "MC_MAC is out of range, MAX_MC_MAC:%d",<br />+                        ZXDH_MAX_MC_MAC_ADDRS);<br />+                return;<br />+            }<br />+        }<br />+    }<br />+    memset(&dev->data->mac_addrs[index], 0, sizeof(struct rte_ether_addr));<br />+}<br />diff --git a/drivers/net/zxdh/zxdh_ethdev_ops.h b/drivers/net/zxdh/zxdh_ethdev_ops.h<br />index c6d6ca56fd..4630bb70db 100644<br />--- a/drivers/net/zxdh/zxdh_ethdev_ops.h<br />+++ b/drivers/net/zxdh/zxdh_ethdev_ops.h<br />@@ -10,5 +10,9 @@<br /> int zxdh_dev_set_link_up(struct rte_eth_dev *dev);<br /> int zxdh_dev_set_link_down(struct rte_eth_dev *dev);<br /> int32_t zxdh_dev_link_update(struct rte_eth_dev *dev, int32_t wait_to_complete __rte_unused);<br />+int zxdh_dev_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,<br />+        uint32_t index, uint32_t vmdq);<br />+int zxdh_dev_mac_addr_set(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr);<br />+void zxdh_dev_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index);<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 9f1e6eed4c..5173fe9185 100644<br />--- a/drivers/net/zxdh/zxdh_msg.h<br />+++ b/drivers/net/zxdh/zxdh_msg.h<br />@@ -46,6 +46,9 @@<br /> #define ZXDH_MSG_REQ_BODY_MAX_LEN  \<br />         (ZXDH_MSG_PAYLOAD_MAX_LEN - ZXDH_MSG_HEAD_LEN)<br />  <br />+#define ZXDH_MAC_FILTER            0xaa<br />+#define ZXDH_MAC_UNFILTER          0xff<br />+<br /> enum ZXDH_DRIVER_TYPE {<br />     ZXDH_MSG_CHAN_END_MPF = 0,<br />     ZXDH_MSG_CHAN_END_PF,<br />@@ -173,6 +176,8 @@ enum zxdh_msg_type {<br />     ZXDH_NULL = 0,<br />     ZXDH_VF_PORT_INIT = 1,<br />     ZXDH_VF_PORT_UNINIT = 2,<br />+    ZXDH_MAC_ADD = 3,<br />+    ZXDH_MAC_DEL = 4,<br />  <br />     ZXDH_PORT_ATTRS_SET = 25,<br />  <br />@@ -321,6 +326,12 @@ struct __rte_packed_begin zxdh_port_attr_set_msg {<br />     uint8_t allmulti_follow;<br /> } __rte_packed_end;<br />  <br />+struct __rte_packed_begin zxdh_mac_filter {<br />+    uint8_t mac_flag;<br />+    uint8_t filter_flag;<br />+    struct rte_ether_addr mac;<br />+} __rte_packed_end;<br />+<br /> struct __rte_packed_begin zxdh_agent_msg_head {<br />     enum zxdh_agent_msg_type msg_type;<br />     uint8_t panel_id;<br />@@ -341,6 +352,7 @@ struct __rte_packed_begin zxdh_msg_info {<br />         struct zxdh_vf_init_msg vf_init_msg;<br />         struct zxdh_port_attr_set_msg port_attr_msg;<br />         struct zxdh_link_info_msg link_msg;<br />+        struct zxdh_mac_filter mac_filter_msg;<br />     } __rte_packed_end data;<br /> } __rte_packed_end;<br />  <br />diff --git a/drivers/net/zxdh/zxdh_np.h b/drivers/net/zxdh/zxdh_np.h<br />index ac3931ba65..19d1f03f59 100644<br />--- a/drivers/net/zxdh/zxdh_np.h<br />+++ b/drivers/net/zxdh/zxdh_np.h<br />@@ -532,6 +532,11 @@ typedef struct zxdh_sdt_tbl_porttbl_t {<br />     uint32_t porttbl_clutch_en;<br /> } ZXDH_SDTTBL_PORTTBL_T;<br />  <br />+typedef struct zxdh_dtb_hash_entry_info_t {<br />+    uint8_t *p_actu_key;<br />+    uint8_t *p_rst;<br />+} ZXDH_DTB_HASH_ENTRY_INFO_T;<br />+<br /> int zxdh_np_host_init(uint32_t dev_id, ZXDH_DEV_INIT_CTRL_T *p_dev_init_ctrl);<br /> int zxdh_np_online_uninit(uint32_t dev_id, char *port_name, uint32_t queue_id);<br /> int zxdh_np_dtb_table_entry_write(uint32_t dev_id, uint32_t queue_id,<br />diff --git a/drivers/net/zxdh/zxdh_tables.c b/drivers/net/zxdh/zxdh_tables.c<br />index db0132ce3f..f5b607584d 100644<br />--- a/drivers/net/zxdh/zxdh_tables.c<br />+++ b/drivers/net/zxdh/zxdh_tables.c<br />@@ -11,6 +11,10 @@<br /> #define ZXDH_SDT_VPORT_ATT_TABLE          1<br /> #define ZXDH_SDT_PANEL_ATT_TABLE          2<br />  <br />+#define ZXDH_MAC_HASH_INDEX_BASE          64<br />+#define ZXDH_MAC_HASH_INDEX(index)        (ZXDH_MAC_HASH_INDEX_BASE + (index))<br />+#define ZXDH_MC_GROUP_NUM                 4<br />+<br /> int<br /> zxdh_set_port_attr(uint16_t vfid, struct zxdh_port_attr_table *port_attr)<br /> {<br />@@ -149,3 +153,196 @@ zxdh_get_port_attr(uint16_t vfid, struct zxdh_port_attr_table *port_attr)<br />  <br />     return ret;<br /> }<br />+<br />+int<br />+zxdh_set_mac_table(uint16_t vport, struct rte_ether_addr *addr,  uint8_t hash_search_idx)<br />+{<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 />+<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 />+<br />+        ZXDH_DTB_HASH_ENTRY_INFO_T dtb_hash_entry = {<br />+            .p_actu_key = (uint8_t *)&unicast_table.key,<br />+            .p_rst = (uint8_t *)&unicast_table.entry<br />+        };<br />+        ZXDH_DTB_USER_ENTRY_T entry_get = {<br />+            .sdt_no = ZXDH_MAC_HASH_INDEX(hash_search_idx),<br />+            .p_entry_data = (void *)&dtb_hash_entry<br />+        };<br />+<br />+        ret = zxdh_np_dtb_table_entry_write(ZXDH_DEVICE_NO,<br />+                    g_dtb_data.queueid, 1, &entry_get);<br />+        if (ret) {<br />+            PMD_DRV_LOG(ERR, "Insert mac_table failed");<br />+            return -ret;<br />+        }<br />+    } else {<br />+        for (group_id = 0; group_id < 4; group_id++) {<br />+            multicast_table.key.vf_group_id = group_id;<br />+            rte_memcpy(multicast_table.key.mac_addr,<br />+                    addr, sizeof(struct rte_ether_addr));<br />+            ZXDH_DTB_HASH_ENTRY_INFO_T dtb_hash_entry = {<br />+                .p_actu_key = (uint8_t *)&multicast_table.key,<br />+                .p_rst = (uint8_t *)&multicast_table.entry<br />+            };<br />+<br />+            ZXDH_DTB_USER_ENTRY_T entry_get = {<br />+                .sdt_no = ZXDH_MAC_HASH_INDEX(hash_search_idx),<br />+                .p_entry_data = (void *)&dtb_hash_entry<br />+            };<br />+<br />+            ret = zxdh_np_dtb_table_entry_get(ZXDH_DEVICE_NO, g_dtb_data.queueid,<br />+                    &entry_get, 1);<br />+            uint8_t index = (vport_num.vfid % 64) / 32;<br />+            if (ret == 0) {<br />+                if (vport_num.vf_flag) {<br />+                    if (group_id == vport_num.vfid / 64)<br />+                        multicast_table.entry.mc_bitmap[index] |=<br />+                            rte_cpu_to_be_32(UINT32_C(1) << <br />+                            (31 - index));<br />+                } else {<br />+                    if (group_id == vport_num.vfid / 64)<br />+                        multicast_table.entry.mc_pf_enable =<br />+                            rte_cpu_to_be_32((1 << 30));<br />+                }<br />+            } else {<br />+                if (vport_num.vf_flag) {<br />+                    if (group_id == vport_num.vfid / 64)<br />+                        multicast_table.entry.mc_bitmap[index] |=<br />+                            rte_cpu_to_be_32(UINT32_C(1) << <br />+                            (31 - index));<br />+                    else<br />+                        multicast_table.entry.mc_bitmap[index] =<br />+                            false;<br />+                } else {<br />+                    if (group_id == vport_num.vfid / 64)<br />+                        multicast_table.entry.mc_pf_enable =<br />+                            rte_cpu_to_be_32((1 << 30));<br />+                    else<br />+                        multicast_table.entry.mc_pf_enable = false;<br />+                }<br />+            }<br />+<br />+            ret = zxdh_np_dtb_table_entry_write(ZXDH_DEVICE_NO, g_dtb_data.queueid,<br />+                        1, &entry_get);<br />+            if (ret) {<br />+                PMD_DRV_LOG(ERR, "add mac_table failed, code:%d", ret);<br />+                return -ret;<br />+            }<br />+        }<br />+    }<br />+    return 0;<br />+}<br />+<br />+int<br />+zxdh_del_mac_table(uint16_t vport, struct rte_ether_addr *addr,  uint8_t hash_search_idx)<br />+{<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 />+<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 />+<br />+        ZXDH_DTB_HASH_ENTRY_INFO_T dtb_hash_entry = {<br />+            .p_actu_key = (uint8_t *)&unicast_table.key,<br />+            .p_rst = (uint8_t *)&unicast_table.entry<br />+        };<br />+<br />+        ZXDH_DTB_USER_ENTRY_T entry_get = {<br />+            .sdt_no = ZXDH_MAC_HASH_INDEX(hash_search_idx),<br />+            .p_entry_data = (void *)&dtb_hash_entry<br />+        };<br />+<br />+        ret = zxdh_np_dtb_table_entry_delete(ZXDH_DEVICE_NO,<br />+                    g_dtb_data.queueid, 1, &entry_get);<br />+        if (ret) {<br />+            PMD_DRV_LOG(ERR, "delete l2_fwd_hash_table failed, code:%d", ret);<br />+            return -ret;<br />+        }<br />+    } else {<br />+        multicast_table.key.vf_group_id = vport_num.vfid / 64;<br />+        rte_memcpy(multicast_table.key.mac_addr, addr, sizeof(struct rte_ether_addr));<br />+<br />+        ZXDH_DTB_HASH_ENTRY_INFO_T dtb_hash_entry = {<br />+            .p_actu_key = (uint8_t *)&multicast_table.key,<br />+            .p_rst = (uint8_t *)&multicast_table.entry<br />+        };<br />+<br />+        ZXDH_DTB_USER_ENTRY_T entry_get = {<br />+            .sdt_no = ZXDH_MAC_HASH_INDEX(hash_search_idx),<br />+            .p_entry_data = (void *)&dtb_hash_entry<br />+        };<br />+<br />+        ret = zxdh_np_dtb_table_entry_get(ZXDH_DEVICE_NO,<br />+                    g_dtb_data.queueid, &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 />+                ~(rte_cpu_to_be_32(UINT32_C(1) << (31 - index)));<br />+        else<br />+            multicast_table.entry.mc_pf_enable = 0;<br />+<br />+        ret = zxdh_np_dtb_table_entry_write(ZXDH_DEVICE_NO,<br />+                    g_dtb_data.queueid, 1, &entry_get);<br />+        if (ret) {<br />+            PMD_DRV_LOG(ERR, "mac_addr_add mc_table failed, code:%d", ret);<br />+            return -ret;<br />+        }<br />+<br />+        for (group_id = 0; group_id < ZXDH_MC_GROUP_NUM; group_id++) {<br />+            multicast_table.key.vf_group_id = group_id;<br />+            rte_memcpy(multicast_table.key.mac_addr, addr,<br />+                sizeof(struct rte_ether_addr));<br />+            ZXDH_DTB_HASH_ENTRY_INFO_T dtb_hash_entry = {<br />+                .p_actu_key = (uint8_t *)&multicast_table.key,<br />+                .p_rst = (uint8_t *)&multicast_table.entry<br />+            };<br />+            ZXDH_DTB_USER_ENTRY_T entry_get = {<br />+                .sdt_no = ZXDH_MAC_HASH_INDEX(hash_search_idx),<br />+                .p_entry_data = (void *)&dtb_hash_entry<br />+            };<br />+<br />+            ret = zxdh_np_dtb_table_entry_get(ZXDH_DEVICE_NO, g_dtb_data.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 />+                if (group_id == (ZXDH_MC_GROUP_NUM - 1))<br />+                    del_flag = 1;<br />+            } else {<br />+                break;<br />+            }<br />+        }<br />+        if (del_flag) {<br />+            for (group_id = 0; group_id < ZXDH_MC_GROUP_NUM; group_id++) {<br />+                multicast_table.key.vf_group_id = group_id;<br />+                rte_memcpy(multicast_table.key.mac_addr, addr,<br />+                    sizeof(struct rte_ether_addr));<br />+                ZXDH_DTB_HASH_ENTRY_INFO_T dtb_hash_entry = {<br />+                    .p_actu_key  = (uint8_t *)&multicast_table.key,<br />+                    .p_rst = (uint8_t *)&multicast_table.entry<br />+                };<br />+                ZXDH_DTB_USER_ENTRY_T entry_get = {<br />+                    .sdt_no  = ZXDH_MAC_HASH_INDEX(hash_search_idx),<br />+                    .p_entry_data = (void *)&dtb_hash_entry<br />+                };<br />+<br />+                ret = zxdh_np_dtb_table_entry_delete(ZXDH_DEVICE_NO,<br />+                            g_dtb_data.queueid, 1, &entry_get);<br />+            }<br />+        }<br />+    }<br />+    return 0;<br />+}<br />diff --git a/drivers/net/zxdh/zxdh_tables.h b/drivers/net/zxdh/zxdh_tables.h<br />index 8676a8b375..f16c4923ef 100644<br />--- a/drivers/net/zxdh/zxdh_tables.h<br />+++ b/drivers/net/zxdh/zxdh_tables.h<br />@@ -142,10 +142,46 @@ struct zxdh_panel_table {<br />     uint32_t rsv_2;<br /> }; /* 16B */<br />  <br />+struct zxdh_mac_unicast_key {<br />+    uint16_t rsv;<br />+    uint8_t  dmac_addr[6];<br />+};<br />+<br />+struct zxdh_mac_unicast_entry {<br />+    uint8_t rsv1     : 7,<br />+            hit_flag : 1;<br />+    uint8_t rsv;<br />+    uint16_t vfid;<br />+};<br />+<br />+struct zxdh_mac_unicast_table {<br />+    struct zxdh_mac_unicast_key key;<br />+    struct zxdh_mac_unicast_entry entry;<br />+};<br />+<br />+struct zxdh_mac_multicast_key {<br />+    uint8_t rsv;<br />+    uint8_t vf_group_id;<br />+    uint8_t mac_addr[6];<br />+};<br />+<br />+struct zxdh_mac_multicast_entry {<br />+    uint32_t mc_pf_enable;<br />+    uint32_t rsv1;<br />+    uint32_t mc_bitmap[2];<br />+};<br />+<br />+struct zxdh_mac_multicast_table {<br />+    struct zxdh_mac_multicast_key key;<br />+    struct zxdh_mac_multicast_entry entry;<br />+};<br />+<br /> int zxdh_port_attr_init(struct rte_eth_dev *dev);<br /> int zxdh_panel_table_init(struct rte_eth_dev *dev);<br /> int zxdh_set_port_attr(uint16_t vfid, struct zxdh_port_attr_table *port_attr);<br /> int zxdh_port_attr_uninit(struct rte_eth_dev *dev);<br /> int zxdh_get_port_attr(uint16_t vfid, struct zxdh_port_attr_table *port_attr);<br />+int zxdh_set_mac_table(uint16_t vport, struct rte_ether_addr *addr,  uint8_t hash_search_idx);<br />+int zxdh_del_mac_table(uint16_t vport, struct rte_ether_addr *addr,  uint8_t hash_search_idx);<br />  <br /> #endif /* ZXDH_TABLES_H */<br />--  <br />2.27.0<br />