optimize mac(add/remove/del) ops. Signed-off-by: Junlong Wang --- drivers/net/zxdh/zxdh_ethdev.c | 40 +++++++++- 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(+), 55 deletions(-) diff --git a/drivers/net/zxdh/zxdh_ethdev.c b/drivers/net/zxdh/zxdh_ethdev.c index 6ac8df4b0d..9393712a31 100644 --- a/drivers/net/zxdh/zxdh_ethdev.c +++ b/drivers/net/zxdh/zxdh_ethdev.c @@ -1157,8 +1157,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, - ð_dev->data->mac_addrs[0], hw->hash_search_index); + ret = zxdh_add_mac_table(hw, hw->vport.vport, + ð_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; @@ -1592,6 +1592,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) { @@ -1667,6 +1700,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; @@ -1681,6 +1716,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 7fe561ae24..deebf075cc 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 bb9d291181..25a33ed493 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; - rte_memcpy(&mac_filter->mac, old_addr, sizeof(struct rte_ether_addr)); - zxdh_msg_head_build(hw, ZXDH_MAC_DEL, &msg_info); + rte_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; - rte_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; + rte_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 __rte_unused, uint32_t ind 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 __rte_unused, uint32_t ind } 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 c109a3601d..aa93c4c26a 100644 --- a/drivers/net/zxdh/zxdh_msg.c +++ b/drivers/net/zxdh/zxdh_msg.c @@ -1270,6 +1270,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, @@ -1278,6 +1300,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; @@ -1289,6 +1312,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; @@ -1301,10 +1330,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; +} + 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 afe0474ebc..51b693bf86 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, @@ -301,6 +303,10 @@ struct zxdh_offset_get_msg { uint16_t type; }; +struct zxdh_mac_reply_msg { + uint8_t mac_flag; +}; + struct __rte_packed_begin zxdh_msg_reply_head { uint8_t flag; uint16_t reps_len; @@ -334,6 +340,7 @@ struct __rte_packed_begin zxdh_msg_reply_body { enum zxdh_reps_flag flag; union __rte_packed_begin { uint8_t reply_data[ZXDH_MSG_REPLY_BODY_MAX_LEN - sizeof(enum zxdh_reps_flag)]; + struct zxdh_mac_reply_msg mac_reply_msg; struct zxdh_hw_np_stats np_stats; struct zxdh_link_info_msg link_msg; struct zxdh_rss_reta rss_reta; 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 f668dad434..7b876d504f 100644 --- a/drivers/net/zxdh/zxdh_tables.h +++ b/drivers/net/zxdh/zxdh_tables.h @@ -150,8 +150,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 { @@ -218,10 +219,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