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