Add zxdh get device backend infos, use msg chan to send msg get. Signed-off-by: Junlong Wang --- drivers/net/zxdh/meson.build | 1 + drivers/net/zxdh/zxdh_common.c | 249 +++++++++++++++++++++++++++++++++ drivers/net/zxdh/zxdh_common.h | 30 ++++ drivers/net/zxdh/zxdh_ethdev.c | 35 +++++ drivers/net/zxdh/zxdh_ethdev.h | 5 + drivers/net/zxdh/zxdh_msg.c | 3 - drivers/net/zxdh/zxdh_msg.h | 24 ++++ 7 files changed, 344 insertions(+), 3 deletions(-) create mode 100644 drivers/net/zxdh/zxdh_common.c create mode 100644 drivers/net/zxdh/zxdh_common.h diff --git a/drivers/net/zxdh/meson.build b/drivers/net/zxdh/meson.build index 2e0c8fddae..a16db47f89 100644 --- a/drivers/net/zxdh/meson.build +++ b/drivers/net/zxdh/meson.build @@ -17,4 +17,5 @@ sources = files( 'zxdh_ethdev.c', 'zxdh_pci.c', 'zxdh_msg.c', + 'zxdh_common.c', ) diff --git a/drivers/net/zxdh/zxdh_common.c b/drivers/net/zxdh/zxdh_common.c new file mode 100644 index 0000000000..61993980c3 --- /dev/null +++ b/drivers/net/zxdh/zxdh_common.c @@ -0,0 +1,249 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2024 ZTE Corporation + */ + +#include +#include + +#include +#include +#include + +#include "zxdh_ethdev.h" +#include "zxdh_logs.h" +#include "zxdh_msg.h" +#include "zxdh_common.h" + +#define ZXDH_MSG_RSP_SIZE_MAX 512 + +#define ZXDH_COMMON_TABLE_READ 0 +#define ZXDH_COMMON_TABLE_WRITE 1 + +#define ZXDH_COMMON_FIELD_PHYPORT 6 + +#define RSC_TBL_CONTENT_LEN_MAX (257 * 2) + +#define REPS_HEADER_PAYLOAD_OFFSET 4 +#define TBL_MSG_PRO_SUCCESS 0xaa + +struct zxdh_common_msg { + uint8_t type; /* 0:read table 1:write table */ + uint8_t field; + uint16_t pcie_id; + uint16_t slen; /* Data length for write table */ + uint16_t reserved; +} __rte_packed; + +struct zxdh_common_rsp_hdr { + uint8_t rsp_status; + uint16_t rsp_len; + uint8_t reserved; + uint8_t payload_status; + uint8_t rsv; + uint16_t payload_len; +} __rte_packed; + +struct tbl_msg_header { + uint8_t type; /* r/w */ + uint8_t field; + uint16_t pcieid; + uint16_t slen; + uint16_t rsv; +}; +struct tbl_msg_reps_header { + uint8_t check; + uint8_t rsv; + uint16_t len; +}; + +static int32_t zxdh_fill_common_msg(struct zxdh_hw *hw, + struct zxdh_pci_bar_msg *desc, + uint8_t type, + uint8_t field, + void *buff, + uint16_t buff_size) +{ + uint64_t msg_len = sizeof(struct zxdh_common_msg) + buff_size; + + desc->payload_addr = rte_zmalloc(NULL, msg_len, 0); + if (unlikely(desc->payload_addr == NULL)) { + PMD_DRV_LOG(ERR, "Failed to allocate msg_data"); + return -ENOMEM; + } + memset(desc->payload_addr, 0, msg_len); + desc->payload_len = msg_len; + struct zxdh_common_msg *msg_data = (struct zxdh_common_msg *)desc->payload_addr; + + msg_data->type = type; + msg_data->field = field; + msg_data->pcie_id = hw->pcie_id; + msg_data->slen = buff_size; + if (buff_size != 0) + rte_memcpy(msg_data + 1, buff, buff_size); + + return 0; +} + +static int32_t zxdh_send_command(struct zxdh_hw *hw, + struct zxdh_pci_bar_msg *desc, + enum bar_module_id module_id, + struct zxdh_msg_recviver_mem *msg_rsp) +{ + desc->virt_addr = (uint64_t)(hw->bar_addr[ZXDH_BAR0_INDEX] + ZXDH_CTRLCH_OFFSET); + desc->src = hw->is_pf ? MSG_CHAN_END_PF : MSG_CHAN_END_VF; + desc->dst = MSG_CHAN_END_RISC; + desc->module_id = module_id; + desc->src_pcieid = hw->pcie_id; + + msg_rsp->buffer_len = ZXDH_MSG_RSP_SIZE_MAX; + msg_rsp->recv_buffer = rte_zmalloc(NULL, msg_rsp->buffer_len, 0); + if (unlikely(msg_rsp->recv_buffer == NULL)) { + PMD_DRV_LOG(ERR, "Failed to allocate messages response"); + return -ENOMEM; + } + + if (zxdh_bar_chan_sync_msg_send(desc, msg_rsp) != BAR_MSG_OK) { + PMD_DRV_LOG(ERR, "Failed to send sync messages or receive response"); + rte_free(msg_rsp->recv_buffer); + return -1; + } + + return 0; +} + +static int32_t zxdh_common_rsp_check(struct zxdh_msg_recviver_mem *msg_rsp, + void *buff, uint16_t len) +{ + struct zxdh_common_rsp_hdr *rsp_hdr = (struct zxdh_common_rsp_hdr *)msg_rsp->recv_buffer; + + if (rsp_hdr->payload_status != 0xaa || rsp_hdr->payload_len != len) { + PMD_DRV_LOG(ERR, "Common response is invalid, status:0x%x rsp_len:%d", + rsp_hdr->payload_status, rsp_hdr->payload_len); + return -1; + } + if (len != 0) + rte_memcpy(buff, rsp_hdr + 1, len); + + return 0; +} + +static int32_t zxdh_common_table_read(struct zxdh_hw *hw, uint8_t field, + void *buff, uint16_t buff_size) +{ + struct zxdh_msg_recviver_mem msg_rsp; + struct zxdh_pci_bar_msg desc; + int32_t ret = 0; + + if (!hw->msg_chan_init) { + PMD_DRV_LOG(ERR, "Bar messages channel not initialized"); + return -1; + } + + ret = zxdh_fill_common_msg(hw, &desc, ZXDH_COMMON_TABLE_READ, field, NULL, 0); + if (ret != 0) { + PMD_DRV_LOG(ERR, "Failed to fill common msg"); + return ret; + } + + ret = zxdh_send_command(hw, &desc, BAR_MODULE_TBL, &msg_rsp); + if (ret != 0) + goto free_msg_data; + + ret = zxdh_common_rsp_check(&msg_rsp, buff, buff_size); + if (ret != 0) + goto free_rsp_data; + +free_rsp_data: + rte_free(msg_rsp.recv_buffer); +free_msg_data: + rte_free(desc.payload_addr); + return ret; +} + +int32_t zxdh_phyport_get(struct rte_eth_dev *dev, uint8_t *phyport) +{ + struct zxdh_hw *hw = dev->data->dev_private; + + int32_t ret = zxdh_common_table_read(hw, ZXDH_COMMON_FIELD_PHYPORT, + (void *)phyport, sizeof(*phyport)); + return ret; +} + +static inline void zxdh_fill_res_para(struct rte_eth_dev *dev, struct zxdh_res_para *param) +{ + struct zxdh_hw *hw = dev->data->dev_private; + + param->pcie_id = hw->pcie_id; + param->virt_addr = hw->bar_addr[0] + ZXDH_CTRLCH_OFFSET; + param->src_type = BAR_MODULE_TBL; +} + +static int zxdh_get_res_info(struct zxdh_res_para *dev, uint8_t field, uint8_t *res, uint16_t *len) +{ + if (!res || !dev) + return BAR_MSG_ERR_NULL; + + struct tbl_msg_header tbl_msg = { + .type = TBL_TYPE_READ, + .field = field, + .pcieid = dev->pcie_id, + .slen = 0, + .rsv = 0, + }; + + struct zxdh_pci_bar_msg in = {0}; + + in.virt_addr = dev->virt_addr; + in.payload_addr = &tbl_msg; + in.payload_len = sizeof(tbl_msg); + in.src = dev->src_type; + in.dst = MSG_CHAN_END_RISC; + in.module_id = BAR_MODULE_TBL; + in.src_pcieid = dev->pcie_id; + + uint8_t recv_buf[RSC_TBL_CONTENT_LEN_MAX + 8] = {0}; + struct zxdh_msg_recviver_mem result = { + .recv_buffer = recv_buf, + .buffer_len = sizeof(recv_buf), + }; + int ret = zxdh_bar_chan_sync_msg_send(&in, &result); + + if (ret != BAR_MSG_OK) { + PMD_DRV_LOG(ERR, + "send sync_msg failed. pcieid: 0x%x, ret: %d.", dev->pcie_id, ret); + return ret; + } + struct tbl_msg_reps_header *tbl_reps = + (struct tbl_msg_reps_header *)(recv_buf + REPS_HEADER_PAYLOAD_OFFSET); + + if (tbl_reps->check != TBL_MSG_PRO_SUCCESS) { + PMD_DRV_LOG(ERR, + "get resource_field failed. pcieid: 0x%x, ret: %d.", dev->pcie_id, ret); + return ret; + } + *len = tbl_reps->len; + memcpy(res, + (recv_buf + REPS_HEADER_PAYLOAD_OFFSET + sizeof(struct tbl_msg_reps_header)), *len); + return ret; +} + +static int zxdh_get_res_panel_id(struct zxdh_res_para *in, uint8_t *panel_id) +{ + uint8_t reps = 0; + uint16_t reps_len = 0; + + if (zxdh_get_res_info(in, TBL_FIELD_PNLID, &reps, &reps_len) != BAR_MSG_OK) + return -1; + + *panel_id = reps; + return BAR_MSG_OK; +} + +int32_t zxdh_pannelid_get(struct rte_eth_dev *dev, uint8_t *pannelid) +{ + struct zxdh_res_para param; + + zxdh_fill_res_para(dev, ¶m); + int32_t ret = zxdh_get_res_panel_id(¶m, pannelid); + return ret; +} diff --git a/drivers/net/zxdh/zxdh_common.h b/drivers/net/zxdh/zxdh_common.h new file mode 100644 index 0000000000..ec7011e820 --- /dev/null +++ b/drivers/net/zxdh/zxdh_common.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2024 ZTE Corporation + */ + +#ifndef _ZXDH_COMMON_H_ +#define _ZXDH_COMMON_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include "zxdh_ethdev.h" + +struct zxdh_res_para { + uint64_t virt_addr; + uint16_t pcie_id; + uint16_t src_type; /* refer to BAR_DRIVER_TYPE */ +}; + +int32_t zxdh_phyport_get(struct rte_eth_dev *dev, uint8_t *phyport); +int32_t zxdh_pannelid_get(struct rte_eth_dev *dev, uint8_t *pannelid); + +#ifdef __cplusplus +} +#endif + +#endif /* _ZXDH_COMMON_H_ */ diff --git a/drivers/net/zxdh/zxdh_ethdev.c b/drivers/net/zxdh/zxdh_ethdev.c index 5002e76e23..e282012afb 100644 --- a/drivers/net/zxdh/zxdh_ethdev.c +++ b/drivers/net/zxdh/zxdh_ethdev.c @@ -10,9 +10,21 @@ #include "zxdh_logs.h" #include "zxdh_pci.h" #include "zxdh_msg.h" +#include "zxdh_common.h" struct zxdh_hw_internal zxdh_hw_internal[RTE_MAX_ETHPORTS]; +uint16_t vport_to_vfid(union VPORT v) +{ + /* epid > 4 is local soft queue. return 1192 */ + if (v.epid > 4) + return 1192; + if (v.vf_flag) + return v.epid * 256 + v.vfid; + else + return (v.epid * 8 + v.pfid) + 1152; +} + static int32_t zxdh_init_device(struct rte_eth_dev *eth_dev) { struct zxdh_hw *hw = eth_dev->data->dev_private; @@ -44,6 +56,25 @@ static int32_t zxdh_init_device(struct rte_eth_dev *eth_dev) return ret; } +static int zxdh_agent_comm(struct rte_eth_dev *eth_dev, struct zxdh_hw *hw) +{ + if (zxdh_phyport_get(eth_dev, &hw->phyport) != 0) { + PMD_INIT_LOG(ERR, "Failed to get phyport"); + return -1; + } + PMD_INIT_LOG(INFO, "Get phyport success: 0x%x", hw->phyport); + + hw->vfid = vport_to_vfid(hw->vport); + + if (zxdh_pannelid_get(eth_dev, &hw->panel_id) != 0) { + PMD_INIT_LOG(ERR, "Failed to get panel_id"); + return -1; + } + PMD_INIT_LOG(INFO, "Get panel id success: 0x%x", hw->panel_id); + + return 0; +} + static int zxdh_eth_dev_init(struct rte_eth_dev *eth_dev) { struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); @@ -103,6 +134,10 @@ static int zxdh_eth_dev_init(struct rte_eth_dev *eth_dev) goto err_zxdh_init; } + ret = zxdh_agent_comm(eth_dev, hw); + if (ret != 0) + goto err_zxdh_init; + return ret; err_zxdh_init: diff --git a/drivers/net/zxdh/zxdh_ethdev.h b/drivers/net/zxdh/zxdh_ethdev.h index a51181f1ce..2351393009 100644 --- a/drivers/net/zxdh/zxdh_ethdev.h +++ b/drivers/net/zxdh/zxdh_ethdev.h @@ -56,6 +56,7 @@ struct zxdh_hw { uint16_t pcie_id; uint16_t device_id; uint16_t port_id; + uint16_t vfid; uint8_t *isr; uint8_t weak_barriers; @@ -63,9 +64,13 @@ struct zxdh_hw { uint8_t mac_addr[RTE_ETHER_ADDR_LEN]; uint8_t duplex; uint8_t is_pf; + uint8_t phyport; + uint8_t panel_id; uint8_t msg_chan_init; }; +uint16_t vport_to_vfid(union VPORT v); + #ifdef __cplusplus } #endif diff --git a/drivers/net/zxdh/zxdh_msg.c b/drivers/net/zxdh/zxdh_msg.c index 3ac4c8d796..e243f97703 100644 --- a/drivers/net/zxdh/zxdh_msg.c +++ b/drivers/net/zxdh/zxdh_msg.c @@ -18,8 +18,6 @@ #define REPS_INFO_FLAG_USABLE 0x00 #define BAR_SEQID_NUM_MAX 256 -#define ZXDH_BAR0_INDEX 0 - #define PCIEID_IS_PF_MASK (0x0800) #define PCIEID_PF_IDX_MASK (0x0700) #define PCIEID_VF_IDX_MASK (0x00ff) @@ -43,7 +41,6 @@ #define FW_SHRD_OFFSET (0x5000) #define FW_SHRD_INNER_HW_LABEL_PAT (0x800) #define HW_LABEL_OFFSET (FW_SHRD_OFFSET + FW_SHRD_INNER_HW_LABEL_PAT) -#define ZXDH_CTRLCH_OFFSET (0x2000) #define CHAN_RISC_SPINLOCK_OFFSET (BAR0_SPINLOCK_OFFSET - BAR0_CHAN_RISC_OFFSET) #define CHAN_PFVF_SPINLOCK_OFFSET (BAR0_SPINLOCK_OFFSET - BAR0_CHAN_PFVF_OFFSET) #define CHAN_RISC_LABEL_OFFSET (HW_LABEL_OFFSET - BAR0_CHAN_RISC_OFFSET) diff --git a/drivers/net/zxdh/zxdh_msg.h b/drivers/net/zxdh/zxdh_msg.h index 06be0f18c8..7379f57d17 100644 --- a/drivers/net/zxdh/zxdh_msg.h +++ b/drivers/net/zxdh/zxdh_msg.h @@ -13,6 +13,9 @@ extern "C" { #include +#define ZXDH_BAR0_INDEX 0 + +#define ZXDH_CTRLCH_OFFSET (0x2000) #define ZXDH_MSIX_INTR_MSG_VEC_BASE 1 #define BAR_MSG_POLLING_SPAN 100 @@ -103,6 +106,27 @@ enum bar_module_id { BAR_MSG_MODULE_NUM = 100, }; +enum RES_TBL_FILED { + TBL_FIELD_PCIEID = 0, + TBL_FIELD_BDF = 1, + TBL_FIELD_MSGCH = 2, + TBL_FIELD_DATACH = 3, + TBL_FIELD_VPORT = 4, + TBL_FIELD_PNLID = 5, + TBL_FIELD_PHYPORT = 6, + TBL_FIELD_SERDES_NUM = 7, + TBL_FIELD_NP_PORT = 8, + TBL_FIELD_SPEED = 9, + TBL_FIELD_HASHID = 10, + TBL_FIELD_NON, +}; + +enum TBL_MSG_TYPE { + TBL_TYPE_READ, + TBL_TYPE_WRITE, + TBL_TYPE_NON, +}; + struct msix_para { uint16_t pcie_id; uint16_t vector_risc; -- 2.27.0