From patchwork Thu Aug 3 08:12:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: 11 X-Patchwork-Id: 129895 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 9022942FC4; Thu, 3 Aug 2023 10:13:51 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 7F2824326B; Thu, 3 Aug 2023 10:13:45 +0200 (CEST) Received: from smtpbg151.qq.com (smtpbg151.qq.com [18.169.211.239]) by mails.dpdk.org (Postfix) with ESMTP id DF0CE43261 for ; Thu, 3 Aug 2023 10:13:43 +0200 (CEST) X-QQ-mid: bizesmtp79t1691050416t1vgp18i Received: from steven.localdomain ( [183.81.182.182]) by bizesmtp.qq.com (ESMTP) with id ; Thu, 03 Aug 2023 16:13:33 +0800 (CST) X-QQ-SSF: 01400000000000D0F000000A0000000 X-QQ-FEAT: vWgqqUtesrkxrGi1YLh00LbqOTxvU83zw6qX80bSsrvAQI8X+7AS91/lRox7S CUm8sU76KJbpxA2ccMQiuInp8RAjS5rFC7xgKubNX+NDb2Z70hke2vYAB2+eSXVQqgWTIVf 4ZhXlk56FNzaOTXFHPFxm7Q1PIPj3BLLA1Jn2f/fX6NG94TGS3x6YQAKzZ/ICetExa6gY+h wZ2CBmv5AZJ5XYrfi1ubpQr9xZFC2q3bbKXR2+7A8D1+F8Kd0JQw3K3aHIntcnflmYyDNto 0LoSeTcK3NEdgnOSv205/wHCdiJoFOEw5mJh/IQL5YkiMBCNq5Kxh4SMDXYDp8pe5hawnAj 5UGarp+JmEXIU9UXbngeOoHEe3bWr/FjgvWhjIDIWmKNX0ZNb/M4atfKDEd4hJ9lxk+SM2G NVWnhwYL7hoYoPpf8XI3AA== X-QQ-GoodBg: 2 X-BIZMAIL-ID: 16881724789796028393 From: Wenbo Cao To: stephen@networkplumber.org, Wenbo Cao Cc: dev@dpdk.org, ferruh.yigit@amd.com, andrew.rybchenko@oktetlabs.ru, yaojun@mucse.com Subject: [PATCH v4 5/8] net/rnp add reset code for Chip Init process Date: Thu, 3 Aug 2023 08:12:58 +0000 Message-Id: <20230803081301.3502865-6-caowenbo@mucse.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20230803081301.3502865-1-caowenbo@mucse.com> References: <20230803081301.3502865-1-caowenbo@mucse.com> MIME-Version: 1.0 X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:mucse.com:qybglogicsvrgz:qybglogicsvrgz5a-0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org we must get the shape info of nic from Firmware for reset. so the related codes is first get firmware info and then reset the chip Signed-off-by: Wenbo Cao --- drivers/net/rnp/base/rnp_hw.h | 56 +++++++++++- drivers/net/rnp/meson.build | 3 + drivers/net/rnp/rnp.h | 27 ++++++ drivers/net/rnp/rnp_ethdev.c | 93 ++++++++++++++++++- drivers/net/rnp/rnp_mbx_fw.h | 163 +++++++++++++++++++++++++++++++++- 5 files changed, 339 insertions(+), 3 deletions(-) diff --git a/drivers/net/rnp/base/rnp_hw.h b/drivers/net/rnp/base/rnp_hw.h index 1db966cf21..57b7dc75a0 100644 --- a/drivers/net/rnp/base/rnp_hw.h +++ b/drivers/net/rnp/base/rnp_hw.h @@ -8,6 +8,9 @@ #include #include "rnp_osdep.h" +#include "rnp_dma_regs.h" +#include "rnp_eth_regs.h" +#include "rnp_cfg.h" static inline unsigned int rnp_rd_reg(volatile void *addr) { @@ -29,7 +32,18 @@ static inline void rnp_wr_reg(volatile void *reg, int val) rnp_rd_reg((uint8_t *)(_base) + (_off)) #define rnp_io_wr(_base, _off, _val) \ rnp_wr_reg((uint8_t *)(_base) + (_off), (_val)) - +#define rnp_eth_rd(_hw, _off) \ + rnp_rd_reg((uint8_t *)((_hw)->eth_base) + (_off)) +#define rnp_eth_wr(_hw, _off, _val) \ + rnp_wr_reg((uint8_t *)((_hw)->eth_base) + (_off), (_val)) +#define rnp_dma_rd(_hw, _off) \ + rnp_rd_reg((uint8_t *)((_hw)->dma_base) + (_off)) +#define rnp_dma_wr(_hw, _off, _val) \ + rnp_wr_reg((uint8_t *)((_hw)->dma_base) + (_off), (_val)) +#define rnp_top_rd(_hw, _off) \ + rnp_rd_reg((uint8_t *)((_hw)->comm_reg_base) + (_off)) +#define rnp_top_wr(_hw, _off, _val) \ + rnp_wr_reg((uint8_t *)((_hw)->comm_reg_base) + (_off), (_val)) struct rnp_hw; /* Mbx Operate info */ enum MBX_ID { @@ -98,6 +112,17 @@ struct rnp_mbx_info { rte_atomic16_t state; } __rte_cache_aligned; +struct rnp_mac_api { + int32_t (*init_hw)(struct rnp_hw *hw); + int32_t (*reset_hw)(struct rnp_hw *hw); +}; + +struct rnp_mac_info { + uint8_t assign_addr[RTE_ETHER_ADDR_LEN]; + uint8_t set_addr[RTE_ETHER_ADDR_LEN]; + struct rnp_mac_api ops; +} __rte_cache_aligned; + struct rnp_eth_adapter; #define RNP_MAX_HW_PORT_PERR_PF (4) struct rnp_hw { @@ -111,8 +136,10 @@ struct rnp_hw { void *eth_base; void *veb_base; void *mac_base[RNP_MAX_HW_PORT_PERR_PF]; + void *comm_reg_base; void *msix_base; /* === dma == */ + void *dev_version; void *dma_axi_en; void *dma_axi_st; @@ -120,10 +147,37 @@ struct rnp_hw { uint16_t vendor_id; uint16_t function; uint16_t pf_vf_num; + int pfvfnum; uint16_t max_vfs; + + bool ncsi_en; + uint8_t ncsi_rar_entries; + + int sgmii_phy_id; + int is_sgmii; + u16 phy_type; + uint8_t force_10g_1g_speed_ablity; + uint8_t force_speed_stat; +#define FORCE_SPEED_STAT_DISABLED (0) +#define FORCE_SPEED_STAT_1G (1) +#define FORCE_SPEED_STAT_10G (2) + uint32_t speed; + unsigned int axi_mhz; + + int fw_version; /* Primary FW Version */ + uint32_t fw_uid; /* Subclass Fw Version */ + + int nic_mode; + unsigned char lane_mask; + int lane_of_port[4]; + char phy_port_ids[4]; /* port id: for lane0~3: value: 0 ~ 7 */ + uint8_t max_port_num; /* Max Port Num This PF Have */ + void *cookie_pool; char cookie_p_name[RTE_MEMZONE_NAMESIZE]; + struct rnp_mac_info mac; struct rnp_mbx_info mbx; + rte_spinlock_t fw_lock; } __rte_cache_aligned; #endif /* __RNP_H__*/ diff --git a/drivers/net/rnp/meson.build b/drivers/net/rnp/meson.build index 38dbee5ca4..c52566c357 100644 --- a/drivers/net/rnp/meson.build +++ b/drivers/net/rnp/meson.build @@ -10,5 +10,8 @@ endif sources = files( 'rnp_ethdev.c', 'rnp_mbx.c', + 'rnp_mbx_fw.c', + 'base/rnp_api.c', ) + includes += include_directories('base') diff --git a/drivers/net/rnp/rnp.h b/drivers/net/rnp/rnp.h index 086667cec1..f6c9231eb1 100644 --- a/drivers/net/rnp/rnp.h +++ b/drivers/net/rnp/rnp.h @@ -13,6 +13,20 @@ #define RNP_CFG_BAR (4) #define RNP_PF_INFO_BAR (0) +enum rnp_resource_share_m { + RNP_SHARE_CORPORATE = 0, + RNP_SHARE_INDEPEND, +}; +/* + * Structure to store private data for each driver instance (for each port). + */ +enum rnp_work_mode { + RNP_SINGLE_40G = 0, + RNP_SINGLE_10G = 1, + RNP_DUAL_10G = 2, + RNP_QUAD_10G = 3, +}; + struct rnp_eth_port { struct rnp_eth_adapter *adapt; struct rnp_hw *hw; @@ -21,9 +35,12 @@ struct rnp_eth_port { struct rnp_share_ops { const struct rnp_mbx_api *mbx_api; + const struct rnp_mac_api *mac_api; } __rte_cache_aligned; struct rnp_eth_adapter { + enum rnp_work_mode mode; + enum rnp_resource_share_m s_mode; /* Port Resource Share Policy */ struct rnp_hw hw; uint16_t max_vfs; struct rte_pci_device *pdev; @@ -31,7 +48,9 @@ struct rnp_eth_adapter { struct rnp_eth_port *ports[RNP_MAX_PORT_OF_PF]; struct rnp_share_ops *share_priv; + int max_link_speed; uint8_t num_ports; /* Cur Pf Has physical Port Num */ + uint8_t lane_mask; } __rte_cache_aligned; #define RNP_DEV_TO_PORT(eth_dev) \ @@ -40,9 +59,14 @@ struct rnp_eth_adapter { ((struct rnp_eth_adapter *)(RNP_DEV_TO_PORT(eth_dev)->adapt)) #define RNP_DEV_TO_HW(eth_dev) \ (&((struct rnp_eth_adapter *)(RNP_DEV_TO_PORT((eth_dev))->adapt))->hw) +#define RNP_HW_TO_ADAPTER(hw) \ + ((struct rnp_eth_adapter *)((hw)->back)) #define RNP_DEV_PP_PRIV_TO_MBX_OPS(dev) \ (((struct rnp_share_ops *)(dev)->process_private)->mbx_api) #define RNP_DEV_TO_MBX_OPS(dev) RNP_DEV_PP_PRIV_TO_MBX_OPS(dev) +#define RNP_DEV_PP_PRIV_TO_MAC_OPS(dev) \ + (((struct rnp_share_ops *)(dev)->process_private)->mac_api) +#define RNP_DEV_TO_MAC_OPS(dev) RNP_DEV_PP_PRIV_TO_MAC_OPS(dev) static inline void rnp_reg_offset_init(struct rnp_hw *hw) { @@ -56,6 +80,7 @@ static inline void rnp_reg_offset_init(struct rnp_hw *hw) hw->msix_base = (void *)((uint8_t *)hw->iobar4 + 0xa4000); } /* === dma status/config====== */ + hw->dev_version = (void *)((uint8_t *)hw->iobar4 + 0x0000); hw->link_sync = (void *)((uint8_t *)hw->iobar4 + 0x000c); hw->dma_axi_en = (void *)((uint8_t *)hw->iobar4 + 0x0010); hw->dma_axi_st = (void *)((uint8_t *)hw->iobar4 + 0x0014); @@ -69,5 +94,7 @@ static inline void rnp_reg_offset_init(struct rnp_hw *hw) /* mac */ for (i = 0; i < RNP_MAX_HW_PORT_PERR_PF; i++) hw->mac_base[i] = (void *)((uint8_t *)hw->iobar4 + 0x60000 + 0x10000 * i); + /* === top reg === */ + hw->comm_reg_base = (void *)((uint8_t *)hw->iobar4 + 0x30000); } #endif /* __RNP_H__ */ diff --git a/drivers/net/rnp/rnp_ethdev.c b/drivers/net/rnp/rnp_ethdev.c index 8a6635951b..13d03a23c5 100644 --- a/drivers/net/rnp/rnp_ethdev.c +++ b/drivers/net/rnp/rnp_ethdev.c @@ -8,7 +8,9 @@ #include #include "rnp.h" +#include "rnp_api.h" #include "rnp_mbx.h" +#include "rnp_mbx_fw.h" #include "rnp_logs.h" static int @@ -92,7 +94,30 @@ rnp_alloc_eth_port(struct rte_pci_device *master_pci, char *name) static void rnp_get_nic_attr(struct rnp_eth_adapter *adapter) { - RTE_SET_USED(adapter); + struct rnp_hw *hw = &adapter->hw; + int lane_mask = 0, err, mode = 0; + + rnp_mbx_link_event_enable(adapter->eth_dev, false); + + err = rnp_mbx_get_capability(adapter->eth_dev, &lane_mask, &mode); + if (err < 0 || !lane_mask) { + PMD_DRV_LOG(ERR, "%s: mbx_get_capability error! errcode=%d\n", + __func__, hw->speed); + return; + } + + adapter->num_ports = __builtin_popcount(lane_mask); + adapter->max_link_speed = hw->speed; + adapter->lane_mask = lane_mask; + adapter->mode = hw->nic_mode; + + PMD_DRV_LOG(INFO, "max link speed:%d lane_mask:0x%x nic-mode:0x%x\n", + (int)adapter->max_link_speed, + (int)adapter->num_ports, adapter->mode); + if (adapter->num_ports && adapter->num_ports == 1) + adapter->s_mode = RNP_SHARE_CORPORATE; + else + adapter->s_mode = RNP_SHARE_INDEPEND; } static int @@ -125,6 +150,72 @@ rnp_process_resource_init(struct rte_eth_dev *eth_dev) return 0; } +static int32_t rnp_init_hw_pf(struct rnp_hw *hw) +{ + struct rnp_eth_adapter *adapter = RNP_HW_TO_ADAPTER(hw); + uint32_t version; + uint32_t reg; + + PMD_INIT_FUNC_TRACE(); + version = rnp_rd_reg(hw->dev_version); + PMD_DRV_LOG(INFO, "NIC HW Version:0x%.2x\n", version); + + /* Disable Rx/Tx Dma */ + rnp_wr_reg(hw->dma_axi_en, false); + /* Check Dma Chanle Status */ + while (rnp_rd_reg(hw->dma_axi_st) == 0) + ; + + /* Reset Nic All Hardware */ + if (rnp_reset_hw(adapter->eth_dev, hw)) + return -EPERM; + + /* Rx Proto Offload No-BYPASS */ + rnp_eth_wr(hw, RNP_ETH_ENGINE_BYPASS, false); + /* Enable Flow Filter Engine */ + rnp_eth_wr(hw, RNP_HOST_FILTER_EN, true); + /* Enable VXLAN Parse */ + rnp_eth_wr(hw, RNP_EN_TUNNEL_VXLAN_PARSE, true); + /* Enabled REDIR ACTION */ + rnp_eth_wr(hw, RNP_REDIR_CTRL, true); + + /* Setup Scatter DMA Mem Size */ + reg = ((RTE_ETHER_MAX_LEN / 16) << RNP_DMA_SCATTER_MEM_SHIFT); + rnp_dma_wr(hw, RNP_DMA_CTRL, reg); +#ifdef PHYTIUM_SUPPORT +#define RNP_DMA_PADDING (1 << 8) + reg = rnp_dma_rd(hw, RNP_DMA_CTRL); + reg |= RNP_DMA_PADDING; + rnp_dma_wr(hw, RNP_DMA_CTRL, reg); +#endif + /* Enable Rx/Tx Dma */ + rnp_wr_reg(hw->dma_axi_en, 0b1111); + + rnp_top_wr(hw, RNP_TX_QINQ_WORKAROUND, 1); + + return 0; +} + +static int32_t rnp_reset_hw_pf(struct rnp_hw *hw) +{ + struct rnp_eth_adapter *adapter = hw->back; + + rnp_top_wr(hw, RNP_NIC_RESET, 0); + rte_wmb(); + rnp_top_wr(hw, RNP_NIC_RESET, 1); + + rnp_mbx_fw_reset_phy(adapter->eth_dev); + + PMD_DRV_LOG(INFO, "PF[%d] reset nic finish\n", + hw->function); + return 0; +} + +const struct rnp_mac_api rnp_mac_ops = { + .reset_hw = rnp_reset_hw_pf, + .init_hw = rnp_init_hw_pf +}; + static void rnp_common_ops_init(struct rnp_eth_adapter *adapter) { diff --git a/drivers/net/rnp/rnp_mbx_fw.h b/drivers/net/rnp/rnp_mbx_fw.h index 439090b5a3..44ffe56908 100644 --- a/drivers/net/rnp/rnp_mbx_fw.h +++ b/drivers/net/rnp/rnp_mbx_fw.h @@ -16,7 +16,168 @@ struct mbx_req_cookie { int priv_len; char priv[RNP_MAX_SHARE_MEM]; }; +enum GENERIC_CMD { + /* link configuration admin commands */ + GET_PHY_ABALITY = 0x0601, + RESET_PHY = 0x0603, + SET_EVENT_MASK = 0x0613, +}; + +enum link_event_mask { + EVT_LINK_UP = 1, + EVT_NO_MEDIA = 2, + EVT_LINK_FAULT = 3, + EVT_PHY_TEMP_ALARM = 4, + EVT_EXCESSIVE_ERRORS = 5, + EVT_SIGNAL_DETECT = 6, + EVT_AUTO_NEGOTIATION_DONE = 7, + EVT_MODULE_QUALIFICATION_FAILD = 8, + EVT_PORT_TX_SUSPEND = 9, +}; + +enum pma_type { + PHY_TYPE_NONE = 0, + PHY_TYPE_1G_BASE_KX, + PHY_TYPE_SGMII, + PHY_TYPE_10G_BASE_KR, + PHY_TYPE_25G_BASE_KR, + PHY_TYPE_40G_BASE_KR4, + PHY_TYPE_10G_BASE_SR, + PHY_TYPE_40G_BASE_SR4, + PHY_TYPE_40G_BASE_CR4, + PHY_TYPE_40G_BASE_LR4, + PHY_TYPE_10G_BASE_LR, + PHY_TYPE_10G_BASE_ER, +}; + +struct phy_abilities { + unsigned char link_stat; + unsigned char lane_mask; + + int speed; + short phy_type; + short nic_mode; + short pfnum; + unsigned int fw_version; + unsigned int axi_mhz; + uint8_t port_ids[4]; + uint32_t fw_uid; + uint32_t phy_id; + + int wol_status; + + union { + unsigned int ext_ablity; + struct { + unsigned int valid : 1; + unsigned int wol_en : 1; + unsigned int pci_preset_runtime_en : 1; + unsigned int smbus_en : 1; + unsigned int ncsi_en : 1; + unsigned int rpu_en : 1; + unsigned int v2 : 1; + unsigned int pxe_en : 1; + unsigned int mctp_en : 1; + } e; + }; +} __rte_packed __rte_aligned(4); + +/* firmware -> driver */ struct mbx_fw_cmd_reply { -} __rte_cache_aligned; + /* fw must set: DD, CMP, Error(if error), copy value */ + unsigned short flags; + /* from command: LB,RD,VFC,BUF,SI,EI,FE */ + unsigned short opcode; /* 2-3: copy from req */ + unsigned short error_code; /* 4-5: 0 if no error */ + unsigned short datalen; /* 6-7: */ + union { + struct { + unsigned int cookie_lo; /* 8-11: */ + unsigned int cookie_hi; /* 12-15: */ + }; + void *cookie; + }; + /* ===== data ==== [16-64] */ + union { + struct phy_abilities phy_abilities; + }; +} __rte_packed __rte_aligned(4); + +#define MBX_REQ_HDR_LEN 24 +/* driver -> firmware */ +struct mbx_fw_cmd_req { + unsigned short flags; /* 0-1 */ + unsigned short opcode; /* 2-3 enum LINK_ADM_CMD */ + unsigned short datalen; /* 4-5 */ + unsigned short ret_value; /* 6-7 */ + union { + struct { + unsigned int cookie_lo; /* 8-11 */ + unsigned int cookie_hi; /* 12-15 */ + }; + void *cookie; + }; + unsigned int reply_lo; /* 16-19 5dw */ + unsigned int reply_hi; /* 20-23 */ + /* === data === [24-64] 7dw */ + union { + struct { + int requester; +#define REQUEST_BY_DPDK 0xa1 +#define REQUEST_BY_DRV 0xa2 +#define REQUEST_BY_PXE 0xa3 + } get_phy_ablity; + + struct { + unsigned short enable_stat; + unsigned short event_mask; /* enum link_event_mask */ + } stat_event_mask; + }; +} __rte_packed __rte_aligned(4); + +static inline void +build_phy_abalities_req(struct mbx_fw_cmd_req *req, void *cookie) +{ + req->flags = 0; + req->opcode = GET_PHY_ABALITY; + req->datalen = 0; + req->reply_lo = 0; + req->reply_hi = 0; + req->cookie = cookie; +} + +/* enum link_event_mask or */ +static inline void +build_link_set_event_mask(struct mbx_fw_cmd_req *req, + unsigned short event_mask, + unsigned short enable, + void *cookie) +{ + req->flags = 0; + req->opcode = SET_EVENT_MASK; + req->datalen = sizeof(req->stat_event_mask); + req->cookie = cookie; + req->reply_lo = 0; + req->reply_hi = 0; + req->stat_event_mask.event_mask = event_mask; + req->stat_event_mask.enable_stat = enable; +} + +static inline void +build_reset_phy_req(struct mbx_fw_cmd_req *req, + void *cookie) +{ + req->flags = 0; + req->opcode = RESET_PHY; + req->datalen = 0; + req->reply_lo = 0; + req->reply_hi = 0; + req->cookie = cookie; +} +int rnp_mbx_get_capability(struct rte_eth_dev *dev, + int *lane_mask, + int *nic_mode); +int rnp_mbx_link_event_enable(struct rte_eth_dev *dev, int enable); +int rnp_mbx_fw_reset_phy(struct rte_eth_dev *dev); #endif /* __RNP_MBX_FW_H__*/