provided msg(pfvf) intr callback for support pf/vf in usermode. Signed-off-by: Junlong Wang --- drivers/net/zxdh/zxdh_ethdev.c | 1 + drivers/net/zxdh/zxdh_msg.c | 186 +++++++++++++++++++++++++++++++-- drivers/net/zxdh/zxdh_msg.h | 9 ++ drivers/net/zxdh/zxdh_tables.c | 17 +++ drivers/net/zxdh/zxdh_tables.h | 2 + 5 files changed, 207 insertions(+), 8 deletions(-) diff --git a/drivers/net/zxdh/zxdh_ethdev.c b/drivers/net/zxdh/zxdh_ethdev.c index 255d4b5b79..6ac8df4b0d 100644 --- a/drivers/net/zxdh/zxdh_ethdev.c +++ b/drivers/net/zxdh/zxdh_ethdev.c @@ -1666,6 +1666,7 @@ zxdh_eth_dev_init(struct rte_eth_dev *eth_dev) goto err_zxdh_init; zxdh_queue_res_get(eth_dev); + zxdh_msg_cb_reg(hw); ret = zxdh_configure_intr(eth_dev); if (ret != 0) goto err_zxdh_init; diff --git a/drivers/net/zxdh/zxdh_msg.c b/drivers/net/zxdh/zxdh_msg.c index 32994b719f..c109a3601d 100644 --- a/drivers/net/zxdh/zxdh_msg.c +++ b/drivers/net/zxdh/zxdh_msg.c @@ -15,6 +15,7 @@ #include "zxdh_logs.h" #include "zxdh_msg.h" #include "zxdh_pci.h" +#include "zxdh_tables.h" #define ZXDH_REPS_INFO_FLAG_USABLE 0x00 #define ZXDH_BAR_SEQID_NUM_MAX 256 @@ -145,7 +146,7 @@ static struct zxdh_seqid_ring g_seqid_ring; static uint8_t tmp_msg_header[ZXDH_BAR_MSG_ADDR_CHAN_INTERVAL]; static rte_spinlock_t chan_lock; -zxdh_bar_chan_msg_recv_callback msg_recv_func_tbl[ZXDH_BAR_MSG_MODULE_NUM]; +zxdh_bar_chan_msg_recv_callback zxdh_msg_recv_func_tbl[ZXDH_BAR_MSG_MODULE_NUM]; static inline const char *zxdh_module_id_name(int val) @@ -923,7 +924,7 @@ zxdh_bar_msg_sync_msg_proc(uint64_t reply_addr, if (reps_buffer == NULL) return; - zxdh_bar_chan_msg_recv_callback recv_func = msg_recv_func_tbl[msg_header->module_id]; + zxdh_bar_chan_msg_recv_callback recv_func = zxdh_msg_recv_func_tbl[msg_header->module_id]; recv_func(receiver_buff, msg_header->len, reps_buffer, &reps_len, dev); msg_header->ack = ZXDH_BAR_CHAN_MSG_ACK; @@ -982,7 +983,7 @@ zxdh_bar_chan_msg_header_check(struct zxdh_bar_msg_header *msg_header) PMD_MSG_LOG(ERR, "recv header ERR: invalid mesg len: %u", len); return ZXDH_BAR_MSG_ERR_LEN; } - if (msg_recv_func_tbl[msg_header->module_id] == NULL) { + if (zxdh_msg_recv_func_tbl[msg_header->module_id] == NULL) { PMD_MSG_LOG(ERR, "recv header ERR: module:%s(%u) doesn't register", zxdh_module_id_name(module_id), module_id); return ZXDH_BAR_MSG_ERR_MODULE_NOEXIST; @@ -1038,7 +1039,8 @@ zxdh_bar_irq_recv(uint8_t src, uint8_t dst, uint64_t virt_addr, void *dev) return ZXDH_BAR_MSG_OK; } -int zxdh_get_bar_offset(struct zxdh_bar_offset_params *paras, +int +zxdh_get_bar_offset(struct zxdh_bar_offset_params *paras, struct zxdh_bar_offset_res *res) { uint16_t check_token; @@ -1082,7 +1084,8 @@ int zxdh_get_bar_offset(struct zxdh_bar_offset_params *paras, return ZXDH_BAR_MSG_OK; } -int zxdh_vf_send_msg_to_pf(struct rte_eth_dev *dev, void *msg_req, +int +zxdh_vf_send_msg_to_pf(struct rte_eth_dev *dev, void *msg_req, uint16_t msg_req_len, void *reply, uint16_t reply_len) { struct zxdh_hw *hw = dev->data->dev_private; @@ -1134,7 +1137,8 @@ int zxdh_vf_send_msg_to_pf(struct rte_eth_dev *dev, void *msg_req, return 0; } -int32_t zxdh_send_msg_to_riscv(struct rte_eth_dev *dev, void *msg_req, +int32_t +zxdh_send_msg_to_riscv(struct rte_eth_dev *dev, void *msg_req, uint16_t msg_req_len, void *reply, uint16_t reply_len, enum ZXDH_BAR_MODULE_ID module_id) { @@ -1182,7 +1186,8 @@ int32_t zxdh_send_msg_to_riscv(struct rte_eth_dev *dev, void *msg_req, return 0; } -void zxdh_msg_head_build(struct zxdh_hw *hw, enum zxdh_msg_type type, +void +zxdh_msg_head_build(struct zxdh_hw *hw, enum zxdh_msg_type type, struct zxdh_msg_info *msg_info) { struct zxdh_msg_head *msghead = &msg_info->msg_head; @@ -1193,7 +1198,8 @@ void zxdh_msg_head_build(struct zxdh_hw *hw, enum zxdh_msg_type type, msghead->pcieid = hw->pcie_id; } -void zxdh_agent_msg_build(struct zxdh_hw *hw, enum zxdh_agent_msg_type type, +void +zxdh_agent_msg_build(struct zxdh_hw *hw, enum zxdh_agent_msg_type type, struct zxdh_msg_info *msg_info) { struct zxdh_agent_msg_head *agent_head = &msg_info->agent_msg_head; @@ -1204,3 +1210,167 @@ void zxdh_agent_msg_build(struct zxdh_hw *hw, enum zxdh_agent_msg_type type, agent_head->vf_id = hw->vfid; agent_head->pcie_id = hw->pcie_id; } + +static int +zxdh_bar_chan_msg_recv_register(uint8_t module_id, zxdh_bar_chan_msg_recv_callback callback) +{ + if (module_id >= (uint16_t)ZXDH_BAR_MSG_MODULE_NUM) { + PMD_MSG_LOG(ERR, "register ERR: invalid module_id: %u.", module_id); + return ZXDH_BAR_MSG_ERR_MODULE; + } + if (callback == NULL) { + PMD_MSG_LOG(ERR, "register %s(%u) error: null callback.", + zxdh_module_id_name(module_id), module_id); + return ZXDH_BAR_MEG_ERR_NULL_FUNC; + } + if (zxdh_msg_recv_func_tbl[module_id] != NULL) { + PMD_MSG_LOG(DEBUG, "register warning, event:%s(%u) already be registered.", + zxdh_module_id_name(module_id), module_id); + return ZXDH_BAR_MSG_ERR_REPEAT_REGISTER; + } + zxdh_msg_recv_func_tbl[module_id] = callback; + return ZXDH_BAR_MSG_OK; +} + +static int +zxdh_vf_port_init(struct zxdh_hw *pf_hw, uint16_t vport, void *cfg_data, + struct zxdh_msg_reply_body *res_info __rte_unused, + uint16_t *res_len __rte_unused) +{ + struct zxdh_port_attr_table port_attr = {0}; + union zxdh_virport_num port = {.vport = vport}; + struct zxdh_vf_init_msg *vf_init_msg = (struct zxdh_vf_init_msg *)cfg_data; + int ret = 0; + + RTE_ASSERT(!cfg_data || !pf_hw || !res_info || !res_len); + *res_len = ZXDH_MSG_REPLYBODY_HEAD; + port_attr.hit_flag = 1; + port_attr.is_vf = 1; + port_attr.phy_port = pf_hw->phyport; + port_attr.is_up = 1; + port_attr.rss_enable = 0; + port_attr.pf_vfid = pf_hw->vfid; + port_attr.hash_search_index = pf_hw->hash_search_index; + port_attr.port_base_qid = vf_init_msg->base_qid; + uint16_t vfid = zxdh_vport_to_vfid(port); + + ret = zxdh_set_port_attr(pf_hw, vfid, &port_attr); + if (ret) { + PMD_DRV_LOG(ERR, "set vport attr failed, code:%d", ret); + goto proc_end; + } + + res_info->flag = ZXDH_REPS_SUCC; + *res_len = sizeof(res_info->flag); + + return ret; +proc_end: + *res_len = sizeof(res_info->flag); + res_info->flag = ZXDH_REPS_FAIL; + return ret; +} + +static int +zxdh_vf_port_uninit(struct zxdh_hw *pf_hw, + uint16_t vport, void *cfg_data __rte_unused, + struct zxdh_msg_reply_body *res_info __rte_unused, + uint16_t *res_len __rte_unused) +{ + char str[ZXDH_MSG_REPLY_BODY_MAX_LEN] = "uninit"; + struct zxdh_port_attr_table port_attr = {0}; + int ret = 0; + + *res_len = ZXDH_MSG_REPLYBODY_HEAD; + RTE_ASSERT(!cfg_data || !pf_hw || !res_info || !res_len); + + ret = zxdh_delete_port_attr(pf_hw, vport, &port_attr); + if (ret) { + PMD_DRV_LOG(ERR, "write port_attr_eram 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; + return ret; + +proc_end: + *res_len += strlen(str); + rte_memcpy(&res_info->reply_data, str, strlen(str) + 1); + 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, +}; + +static inline int +zxdh_config_process_callback(struct zxdh_hw *hw, struct zxdh_msg_info *msg_info, + struct zxdh_msg_reply_body *res, uint16_t *res_len) +{ + struct zxdh_msg_head *msghead = &msg_info->msg_head; + int ret = -1; + + if (!res || !res_len) { + PMD_DRV_LOG(ERR, " invalid param"); + return -1; + } + if (zxdh_proc_cb[msghead->msg_type]) { + ret = zxdh_proc_cb[msghead->msg_type](hw, msghead->vport, + (void *)&msg_info->data, res, res_len); + if (!ret) + res->flag = ZXDH_REPS_SUCC; + else + res->flag = ZXDH_REPS_FAIL; + } else { + res->flag = ZXDH_REPS_INVALID; + } + *res_len += sizeof(res->flag); + return ret; +} + +static int +pf_recv_bar_msg(void *pay_load, uint16_t len, void *reps_buffer, + uint16_t *reps_len, void *eth_dev __rte_unused) +{ + struct zxdh_msg_info *msg_info = (struct zxdh_msg_info *)pay_load; + struct zxdh_msg_reply_body *reply_body = reps_buffer; + struct rte_eth_dev *dev = (struct rte_eth_dev *)eth_dev; + int32_t ret = 0; + struct zxdh_hw *hw; + uint16_t reply_len = 0; + + if (eth_dev == NULL) { + PMD_DRV_LOG(ERR, "param invalid, dev is null."); + ret = -2; + goto msg_proc_end; + } + hw = dev->data->dev_private; + + if (msg_info->msg_head.msg_type >= ZXDH_MSG_TYPE_END) { + PMD_DRV_LOG(ERR, "len %u msg_type %d unsupported", + len, msg_info->msg_head.msg_type); + ret = -2; + goto msg_proc_end; + } + + ret = zxdh_config_process_callback(hw, msg_info, reply_body, &reply_len); + *reps_len = reply_len + sizeof(struct zxdh_msg_reply_head); + return ret; + +msg_proc_end: + memcpy(reply_body->reply_data, &ret, sizeof(ret)); + reply_len = sizeof(ret); + *reps_len = sizeof(struct zxdh_msg_reply_head) + reply_len; + return ret; +} + +void +zxdh_msg_cb_reg(struct zxdh_hw *hw) +{ + if (hw->is_pf) + zxdh_bar_chan_msg_recv_register(ZXDH_MODULE_BAR_MSG_TO_PF, pf_recv_bar_msg); +} diff --git a/drivers/net/zxdh/zxdh_msg.h b/drivers/net/zxdh/zxdh_msg.h index 6f657da434..afe0474ebc 100644 --- a/drivers/net/zxdh/zxdh_msg.h +++ b/drivers/net/zxdh/zxdh_msg.h @@ -310,6 +310,7 @@ struct __rte_packed_begin zxdh_msg_reply_head { enum zxdh_reps_flag { ZXDH_REPS_FAIL, ZXDH_REPS_SUCC = 0xaa, + ZXDH_REPS_INVALID = 0xee, }; struct __rte_packed_begin zxdh_link_info_msg { @@ -428,6 +429,13 @@ struct __rte_packed_begin zxdh_msg_info { typedef int (*zxdh_bar_chan_msg_recv_callback)(void *pay_load, uint16_t len, void *reps_buffer, uint16_t *reps_len, void *dev); +typedef int (*zxdh_msg_process_callback)(struct zxdh_hw *hw, uint16_t vport, void *cfg_data, + struct zxdh_msg_reply_body *res_info, uint16_t *res_len); +extern zxdh_msg_process_callback zxdh_proc_cb[]; + +typedef int (*zxdh_bar_chan_msg_recv_callback)(void *pay_load, uint16_t len, + void *reps_buffer, uint16_t *reps_len, void *dev); +extern zxdh_bar_chan_msg_recv_callback zxdh_msg_recv_func_tbl[ZXDH_BAR_MSG_MODULE_NUM]; int zxdh_get_bar_offset(struct zxdh_bar_offset_params *paras, struct zxdh_bar_offset_res *res); int zxdh_msg_chan_init(void); @@ -448,5 +456,6 @@ void zxdh_agent_msg_build(struct zxdh_hw *hw, enum zxdh_agent_msg_type type, int32_t zxdh_send_msg_to_riscv(struct rte_eth_dev *dev, void *msg_req, uint16_t msg_req_len, void *reply, uint16_t reply_len, enum ZXDH_BAR_MODULE_ID module_id); +void zxdh_msg_cb_reg(struct zxdh_hw *hw); #endif /* ZXDH_MSG_H */ diff --git a/drivers/net/zxdh/zxdh_tables.c b/drivers/net/zxdh/zxdh_tables.c index f169eca575..a5d598d022 100644 --- a/drivers/net/zxdh/zxdh_tables.c +++ b/drivers/net/zxdh/zxdh_tables.c @@ -214,6 +214,23 @@ zxdh_get_port_attr(struct zxdh_hw *hw, uint16_t vport, struct zxdh_port_attr_tab return ret; } +int +zxdh_delete_port_attr(struct zxdh_hw *hw, uint16_t vport, + struct zxdh_port_attr_table *port_attr) +{ + struct zxdh_dtb_shared_data *dtb_data = &hw->dev_sd->dtb_sd; + union zxdh_virport_num vport_num = (union zxdh_virport_num)vport; + ZXDH_DTB_ERAM_ENTRY_INFO_T entry = {vport_num.vfid, (uint32_t *)port_attr}; + ZXDH_DTB_USER_ENTRY_T user_entry = { + .sdt_no = ZXDH_SDT_VPORT_ATT_TABLE, + .p_entry_data = (void *)&entry + }; + int ret = zxdh_np_dtb_table_entry_delete(hw->slot_id, dtb_data->queueid, 1, &user_entry); + if (ret != 0) + PMD_DRV_LOG(ERR, "delete port attr failed, vfid:%u", vport_num.vfid); + return ret; +} + int zxdh_set_mac_table(struct zxdh_hw *hw, uint16_t vport, struct rte_ether_addr *addr, uint8_t hash_search_idx) diff --git a/drivers/net/zxdh/zxdh_tables.h b/drivers/net/zxdh/zxdh_tables.h index d800faee3e..f668dad434 100644 --- a/drivers/net/zxdh/zxdh_tables.h +++ b/drivers/net/zxdh/zxdh_tables.h @@ -216,6 +216,8 @@ int zxdh_set_port_attr(struct zxdh_hw *hw, uint16_t vport, int zxdh_port_attr_uninit(struct rte_eth_dev *dev); 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, -- 2.27.0