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 <caowe...@mucse.com>
---
 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 <ethdev_driver.h>
 
 #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 <ethdev_driver.h>
 
 #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__*/
-- 
2.27.0

Reply via email to