From: Wenbo Cao <caowenbo@mucse.com>
To: thomas@monjalon.net, Wenbo Cao <caowenbo@mucse.com>,
Anatoly Burakov <anatoly.burakov@intel.com>
Cc: stephen@networkplumber.org, dev@dpdk.org, ferruh.yigit@amd.com,
andrew.rybchenko@oktetlabs.ru, yaojun@mucse.com
Subject: [PATCH v7 05/28] net/rnp: add device init and uninit
Date: Sat, 8 Feb 2025 10:43:42 +0800 [thread overview]
Message-ID: <1738982645-34550-6-git-send-email-caowenbo@mucse.com> (raw)
In-Reply-To: <1738982645-34550-1-git-send-email-caowenbo@mucse.com>
add firmware communic method and basic device
init, uninit and close resource function.
Signed-off-by: Wenbo Cao <caowenbo@mucse.com>
Reviewed-by: Ferruh Yigit <ferruh.yigit@amd.com>
---
drivers/net/rnp/base/meson.build | 4 +
drivers/net/rnp/base/rnp_common.c | 73 ++++++++
drivers/net/rnp/base/rnp_common.h | 12 ++
drivers/net/rnp/base/rnp_dma_regs.h | 13 ++
drivers/net/rnp/base/rnp_eth_regs.h | 15 ++
drivers/net/rnp/base/rnp_fw_cmd.c | 75 ++++++++
drivers/net/rnp/base/rnp_fw_cmd.h | 216 +++++++++++++++++++++++
drivers/net/rnp/base/rnp_hw.h | 39 +++++
drivers/net/rnp/base/rnp_mac.c | 28 +++
drivers/net/rnp/base/rnp_mac.h | 14 ++
drivers/net/rnp/base/rnp_mbx_fw.c | 338 ++++++++++++++++++++++++++++++++++++
drivers/net/rnp/base/rnp_mbx_fw.h | 18 ++
drivers/net/rnp/base/rnp_osdep.h | 100 ++++++++++-
drivers/net/rnp/meson.build | 1 +
drivers/net/rnp/rnp.h | 40 +++++
drivers/net/rnp/rnp_ethdev.c | 317 ++++++++++++++++++++++++++++++++-
16 files changed, 1290 insertions(+), 13 deletions(-)
create mode 100644 drivers/net/rnp/base/rnp_common.c
create mode 100644 drivers/net/rnp/base/rnp_common.h
create mode 100644 drivers/net/rnp/base/rnp_dma_regs.h
create mode 100644 drivers/net/rnp/base/rnp_eth_regs.h
create mode 100644 drivers/net/rnp/base/rnp_fw_cmd.c
create mode 100644 drivers/net/rnp/base/rnp_fw_cmd.h
create mode 100644 drivers/net/rnp/base/rnp_mac.c
create mode 100644 drivers/net/rnp/base/rnp_mac.h
create mode 100644 drivers/net/rnp/base/rnp_mbx_fw.c
create mode 100644 drivers/net/rnp/base/rnp_mbx_fw.h
diff --git a/drivers/net/rnp/base/meson.build b/drivers/net/rnp/base/meson.build
index 9ea88c3..b9db033 100644
--- a/drivers/net/rnp/base/meson.build
+++ b/drivers/net/rnp/base/meson.build
@@ -3,6 +3,10 @@
sources = [
'rnp_mbx.c',
+ 'rnp_fw_cmd.c',
+ 'rnp_mbx_fw.c',
+ 'rnp_common.c',
+ 'rnp_mac.c',
]
error_cflags = ['-Wno-unused-value',
diff --git a/drivers/net/rnp/base/rnp_common.c b/drivers/net/rnp/base/rnp_common.c
new file mode 100644
index 0000000..47a979b
--- /dev/null
+++ b/drivers/net/rnp/base/rnp_common.c
@@ -0,0 +1,73 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Mucse IC Design Ltd.
+ */
+
+#include "rnp_osdep.h"
+#include "rnp_hw.h"
+#include "rnp_eth_regs.h"
+#include "rnp_dma_regs.h"
+#include "rnp_common.h"
+#include "rnp_mbx_fw.h"
+#include "rnp_mac.h"
+#include "../rnp.h"
+
+static void
+rnp_hw_reset(struct rnp_hw *hw)
+{
+ PMD_INIT_FUNC_TRACE();
+
+ RNP_E_REG_WR(hw, RNP_NIC_RESET, 0);
+ /* hardware reset valid must be 0 -> 1 */
+ wmb();
+ RNP_E_REG_WR(hw, RNP_NIC_RESET, 1);
+ RNP_PMD_DRV_LOG(INFO, "PF[%d] reset nic finish\n", hw->mbx.pf_num);
+}
+
+int rnp_init_hw(struct rnp_hw *hw)
+{
+ struct rnp_eth_port *port = RNP_DEV_TO_PORT(hw->back->eth_dev);
+ u32 version = 0;
+ int ret = -1;
+ u32 state;
+
+ PMD_INIT_FUNC_TRACE();
+ version = RNP_E_REG_RD(hw, RNP_DMA_VERSION);
+ RNP_PMD_DRV_LOG(INFO, "nic hw version:0x%.2x\n", version);
+ rnp_fw_init(hw);
+ RNP_E_REG_WR(hw, RNP_DMA_HW_EN, FALSE);
+ do {
+ state = RNP_E_REG_RD(hw, RNP_DMA_HW_STATE);
+ } while (state == 0);
+ ret = rnp_mbx_fw_get_capability(port);
+ if (ret) {
+ RNP_PMD_ERR("mbx_get_capability error! errcode=%d\n", ret);
+ return ret;
+ }
+ rnp_hw_reset(hw);
+ rnp_mbx_fw_reset_phy(hw);
+ /* rx packet protocol engine bypass */
+ RNP_E_REG_WR(hw, RNP_E_ENG_BYPASS, FALSE);
+ /* enable host filter */
+ RNP_E_REG_WR(hw, RNP_E_FILTER_EN, TRUE);
+ /* enable vxlan parse */
+ RNP_E_REG_WR(hw, RNP_E_VXLAN_PARSE_EN, TRUE);
+ /* enable flow direct engine */
+ RNP_E_REG_WR(hw, RNP_E_REDIR_EN, TRUE);
+ /* enable dma engine */
+ RNP_E_REG_WR(hw, RNP_DMA_HW_EN, RNP_DMA_EN_ALL);
+#define RNP_TARGET_TC_PORT (2)
+#define RNP_PORT_OFF_QUEUE_NUM (2)
+ if (hw->nic_mode == RNP_DUAL_10G && hw->max_port_num == 2)
+ RNP_E_REG_WR(hw, RNP_TC_PORT_OFFSET(RNP_TARGET_TC_PORT),
+ RNP_PORT_OFF_QUEUE_NUM);
+
+ return 0;
+}
+
+int
+rnp_setup_common_ops(struct rnp_hw *hw)
+{
+ rnp_mac_ops_init(hw);
+
+ return 0;
+}
diff --git a/drivers/net/rnp/base/rnp_common.h b/drivers/net/rnp/base/rnp_common.h
new file mode 100644
index 0000000..aaf77a6
--- /dev/null
+++ b/drivers/net/rnp/base/rnp_common.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Mucse IC Design Ltd.
+ */
+
+#ifndef _RNP_COMMON_H_
+#define _RNP_COMMON_H_
+
+#define RNP_NIC_RESET _NIC_(0x0010)
+int rnp_init_hw(struct rnp_hw *hw);
+int rnp_setup_common_ops(struct rnp_hw *hw);
+
+#endif /* _RNP_COMMON_H_ */
diff --git a/drivers/net/rnp/base/rnp_dma_regs.h b/drivers/net/rnp/base/rnp_dma_regs.h
new file mode 100644
index 0000000..00f8aff
--- /dev/null
+++ b/drivers/net/rnp/base/rnp_dma_regs.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Mucse IC Design Ltd.
+ */
+
+#ifndef _RNP_DMA_REGS_H_
+#define _RNP_DMA_REGS_H_
+
+#define RNP_DMA_VERSION (0)
+#define RNP_DMA_HW_EN (0x10)
+#define RNP_DMA_EN_ALL (0b1111)
+#define RNP_DMA_HW_STATE (0x14)
+
+#endif /* _RNP_DMA_REGS_H_ */
diff --git a/drivers/net/rnp/base/rnp_eth_regs.h b/drivers/net/rnp/base/rnp_eth_regs.h
new file mode 100644
index 0000000..6957866
--- /dev/null
+++ b/drivers/net/rnp/base/rnp_eth_regs.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Mucse IC Design Ltd.
+ */
+
+#ifndef _RNP_ETH_REGS_H
+#define _RNP_ETH_REGS_H
+
+#define RNP_E_ENG_BYPASS _ETH_(0x8000)
+#define RNP_E_VXLAN_PARSE_EN _ETH_(0x8004)
+#define RNP_E_FILTER_EN _ETH_(0x801c)
+#define RNP_E_REDIR_EN _ETH_(0x8030)
+
+#define RNP_TC_PORT_OFFSET(lane) _ETH_(0xe840 + 0x04 * (lane))
+
+#endif /* _RNP_ETH_REGS_H */
diff --git a/drivers/net/rnp/base/rnp_fw_cmd.c b/drivers/net/rnp/base/rnp_fw_cmd.c
new file mode 100644
index 0000000..064ba9e
--- /dev/null
+++ b/drivers/net/rnp/base/rnp_fw_cmd.c
@@ -0,0 +1,75 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Mucse IC Design Ltd.
+ */
+
+#include "rnp_fw_cmd.h"
+
+static void
+rnp_build_phy_abalities_req(struct rnp_mbx_fw_cmd_req *req,
+ struct rnp_fw_req_arg *req_arg,
+ void *cookie)
+{
+ struct rnp_get_phy_ablity *arg = (struct rnp_get_phy_ablity *)req->data;
+
+ req->flags = 0;
+ req->opcode = RNP_GET_PHY_ABALITY;
+ req->datalen = sizeof(*arg);
+ req->cookie = cookie;
+ req->reply_lo = 0;
+ req->reply_hi = 0;
+
+ arg->requester = RNP_REQUEST_BY_DPDK;
+}
+
+static void
+rnp_build_reset_phy_req(struct rnp_mbx_fw_cmd_req *req,
+ void *cookie)
+{
+ req->flags = 0;
+ req->opcode = RNP_RESET_PHY;
+ req->datalen = 0;
+ req->reply_lo = 0;
+ req->reply_hi = 0;
+ req->cookie = cookie;
+}
+
+static void
+rnp_build_get_macaddress_req(struct rnp_mbx_fw_cmd_req *req,
+ struct rnp_fw_req_arg *req_arg,
+ void *cookie)
+{
+ struct rnp_mac_addr_req *arg = (struct rnp_mac_addr_req *)req->data;
+
+ req->flags = 0;
+ req->opcode = RNP_GET_MAC_ADDRESS;
+ req->datalen = sizeof(*arg);
+ req->cookie = cookie;
+ req->reply_lo = 0;
+ req->reply_hi = 0;
+
+ arg->lane_mask = RTE_BIT32(req_arg->param0);
+ arg->pfvf_num = req_arg->param1;
+}
+
+int rnp_build_fwcmd_req(struct rnp_mbx_fw_cmd_req *req,
+ struct rnp_fw_req_arg *arg,
+ void *cookie)
+{
+ int err = 0;
+
+ switch (arg->opcode) {
+ case RNP_GET_PHY_ABALITY:
+ rnp_build_phy_abalities_req(req, arg, cookie);
+ break;
+ case RNP_RESET_PHY:
+ rnp_build_reset_phy_req(req, cookie);
+ break;
+ case RNP_GET_MAC_ADDRESS:
+ rnp_build_get_macaddress_req(req, arg, cookie);
+ break;
+ default:
+ err = -EOPNOTSUPP;
+ }
+
+ return err;
+}
diff --git a/drivers/net/rnp/base/rnp_fw_cmd.h b/drivers/net/rnp/base/rnp_fw_cmd.h
new file mode 100644
index 0000000..fb7a0af
--- /dev/null
+++ b/drivers/net/rnp/base/rnp_fw_cmd.h
@@ -0,0 +1,216 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Mucse IC Design Ltd.
+ */
+
+#ifndef _RNP_FW_CMD_H_
+#define _RNP_FW_CMD_H_
+
+#include "rnp_osdep.h"
+
+#define RNP_FW_LINK_SYNC _NIC_(0x000c)
+#define RNP_LINK_MAGIC_CODE (0xa5a40000)
+#define RNP_LINK_MAGIC_MASK RTE_GENMASK32(31, 16)
+
+enum RNP_GENERIC_CMD {
+ /* general */
+ RNP_GET_FW_VERSION = 0x0001,
+ RNP_READ_REG = 0xFF03,
+ RNP_WRITE_REG = 0xFF04,
+ RNP_MODIFY_REG = 0xFF07,
+
+ /* virtualization */
+ RNP_IFUP_DOWN = 0x0800,
+ RNP_PTP_EVENT = 0x0801,
+ RNP_DRIVER_INSMOD = 0x0803,
+ RNP_SYSTEM_SUSPUSE = 0x0804,
+ RNP_FORCE_LINK_ON_CLOSE = 0x0805,
+
+ /* link configuration admin commands */
+ RNP_GET_PHY_ABALITY = 0x0601,
+ RNP_GET_MAC_ADDRESS = 0x0602,
+ RNP_RESET_PHY = 0x0603,
+ RNP_LED_SET = 0x0604,
+ RNP_GET_LINK_STATUS = 0x0607,
+ RNP_LINK_STATUS_EVENT = 0x0608,
+ RNP_SET_LANE_FUN = 0x0609,
+ RNP_GET_LANE_STATUS = 0x0610,
+ RNP_SFP_SPEED_CHANGED_EVENT = 0x0611,
+ RNP_SET_EVENT_MASK = 0x0613,
+ RNP_SET_LANE_EVENT_EN = 0x0614,
+ RNP_SET_LOOPBACK_MODE = 0x0618,
+ RNP_PLUG_EVENT = 0x0620,
+ RNP_SET_PHY_REG = 0x0628,
+ RNP_GET_PHY_REG = 0x0629,
+ RNP_PHY_LINK_SET = 0x0630,
+ RNP_GET_PHY_STATISTICS = 0x0631,
+ RNP_GET_PCS_REG = 0x0633,
+ RNP_MODIFY_PCS_REG = 0x0634,
+ RNP_MODIFY_PHY_REG = 0x0635,
+
+ /*sfp-module*/
+ RNP_SFP_MODULE_READ = 0x0900,
+ RNP_SFP_MODULE_WRITE = 0x0901,
+
+ /* fw update */
+ RNP_FW_UPDATE = 0x0700,
+ RNP_FW_MAINTAIN = 0x0701,
+ RNP_EEPROM_OP = 0x0705,
+ RNP_EMI_SYNC = 0x0706,
+
+ RNP_GET_DUMP = 0x0a00,
+ RNP_SET_DUMP = 0x0a10,
+ RNP_GET_TEMP = 0x0a11,
+ RNP_SET_WOL = 0x0a12,
+ RNP_LLDP_TX_CTL = 0x0a13,
+ RNP_LLDP_STAT = 0x0a14,
+ RNP_SFC_OP = 0x0a15,
+ RNP_SRIOV_SET = 0x0a16,
+ RNP_SRIOV_STAT = 0X0a17,
+
+ RNP_SN_PN = 0x0b00,
+
+ RNP_ATU_OBOUND_SET = 0xFF10,
+ RNP_SET_DDR_CSL = 0xFF11,
+};
+
+/* firmware -> driver reply */
+struct rnp_phy_abilities_rep {
+ u8 link_stat;
+ u8 lane_mask;
+
+ u32 speed;
+ u16 phy_type;
+ u16 nic_mode;
+ u16 pfnum;
+ u32 fw_version;
+ u32 nic_clock;
+ union {
+ u8 port_ids[4];
+ u32 port_idf;
+ };
+ u32 fw_ext;
+ u32 phy_id;
+ u32 wol_status; /* bit0-3 wol supported . bit4-7 wol enable */
+ union {
+ u32 ext_ablity;
+ struct {
+ u32 valid : 1; /* 0 */
+ u32 wol_en : 1; /* 1 */
+ u32 pci_preset_runtime_en : 1; /* 2 */
+ u32 smbus_en : 1; /* 3 */
+ u32 ncsi_en : 1; /* 4 */
+ u32 rpu_en : 1; /* 5 */
+ u32 v2 : 1; /* 6 */
+ u32 pxe_en : 1; /* 7 */
+ u32 mctp_en : 1; /* 8 */
+ u32 yt8614 : 1; /* 9 */
+ u32 pci_ext_reset : 1; /* 10 */
+ u32 rpu_availble : 1; /* 11 */
+ u32 fw_lldp_ablity : 1; /* 12 */
+ u32 lldp_enabled : 1; /* 13 */
+ u32 only_1g : 1; /* 14 */
+ u32 force_link_down_en : 4; /* lane0 - lane4 */
+ u32 force_link_supported : 1;
+ u32 ports_is_sgmii_valid : 1;
+ u32 lane_is_sgmii : 4; /* 24 bit */
+ u32 rsvd : 7;
+ } e;
+ };
+} _PACKED_ALIGN4;
+
+struct rnp_mac_addr_rep {
+ u32 lanes;
+ struct _addr {
+ /* for macaddr:01:02:03:04:05:06
+ * mac-hi=0x01020304 mac-lo=0x05060000
+ */
+ u8 mac[8];
+ } addrs[4];
+ u32 pcode;
+};
+
+#define RNP_FW_REP_DATA_NUM (40)
+struct rnp_mbx_fw_cmd_reply {
+ u16 flags;
+ u16 opcode;
+ u16 error_code;
+ u16 datalen;
+ union {
+ struct {
+ u32 cookie_lo;
+ u32 cookie_hi;
+ };
+ void *cookie;
+ };
+ u8 data[RNP_FW_REP_DATA_NUM];
+} _PACKED_ALIGN4;
+
+struct rnp_fw_req_arg {
+ u16 opcode;
+ u32 param0;
+ u32 param1;
+ u32 param2;
+ u32 param3;
+ u32 param4;
+ u32 param5;
+};
+
+static_assert(sizeof(struct rnp_mbx_fw_cmd_reply) == 56,
+ "firmware request cmd size changed: rnp_mbx_fw_cmd_reply");
+
+#define RNP_FW_REQ_DATA_NUM (32)
+/* driver op -> firmware */
+struct rnp_mac_addr_req {
+ u32 lane_mask;
+ u32 pfvf_num;
+ u32 rsv[2];
+} _PACKED_ALIGN4;
+
+struct rnp_get_phy_ablity {
+ u32 requester;
+#define RNP_REQUEST_BY_DPDK (0xa1)
+#define RNP_REQUEST_BY_DRV (0xa2)
+#define RNP_REQUEST_BY_PXE (0xa3)
+ u32 rsv[7];
+} _PACKED_ALIGN4;
+
+struct rnp_mbx_fw_cmd_req {
+ u16 flags;
+ u16 opcode;
+ u16 datalen;
+ u16 ret_value;
+ union {
+ struct {
+ u32 cookie_lo; /* 8-11 */
+ u32 cookie_hi; /* 12-15 */
+ };
+ void *cookie;
+ };
+ u32 reply_lo;
+ u32 reply_hi;
+
+ u8 data[RNP_FW_REQ_DATA_NUM];
+} _PACKED_ALIGN4;
+
+static_assert(sizeof(struct rnp_mbx_fw_cmd_req) == 56,
+ "firmware request cmd size changed: rnp_mbx_fw_cmd_req");
+
+#define RNP_MBX_REQ_HDR_LEN (24)
+#define RNP_MBX_REPLYHDR_LEN (16)
+#define RNP_MAX_SHARE_MEM (8 * 8)
+struct rnp_mbx_req_cookie {
+ u32 magic;
+#define RNP_COOKIE_MAGIC (0xCE)
+ u32 timeout_ms;
+ u32 errcode;
+
+ /* wait_queue_head_t wait; */
+ volatile u32 done;
+ u32 priv_len;
+ u8 priv[RNP_MAX_SHARE_MEM];
+};
+
+int rnp_build_fwcmd_req(struct rnp_mbx_fw_cmd_req *req,
+ struct rnp_fw_req_arg *arg,
+ void *cookie);
+#endif /* _RNP_FW_CMD_H */
diff --git a/drivers/net/rnp/base/rnp_hw.h b/drivers/net/rnp/base/rnp_hw.h
index 959b4c3..e150543 100644
--- a/drivers/net/rnp/base/rnp_hw.h
+++ b/drivers/net/rnp/base/rnp_hw.h
@@ -6,6 +6,8 @@
#include "rnp_osdep.h"
+#define RNP_MAX_PORT_OF_PF (4)
+
struct rnp_hw;
/* Mailbox Operate Info */
enum RNP_MBX_ID {
@@ -55,7 +57,34 @@ struct rnp_mbx_info {
struct rnp_mbx_sync syncs[RNP_MBX_FW];
};
+struct rnp_eth_port;
+/* mac operations */
+struct rnp_mac_ops {
+ /* update mac packet filter mode */
+ int (*get_macaddr)(struct rnp_eth_port *port, u8 *mac);
+};
+
struct rnp_eth_adapter;
+struct rnp_fw_info {
+ char cookie_name[RTE_MEMZONE_NAMESIZE];
+ struct rnp_dma_mem mem;
+ void *cookie_pool;
+ bool fw_irq_en;
+ bool msg_alloced;
+
+ u64 fw_features;
+ spinlock_t fw_lock;
+};
+
+#define rnp_call_hwif_impl(port, func, arg...) \
+ (((func) != NULL) ? ((func) (port, arg)) : (-ENODEV))
+
+enum rnp_nic_mode {
+ RNP_SINGLE_40G = 0,
+ RNP_SINGLE_10G = 1,
+ RNP_DUAL_10G = 2,
+ RNP_QUAD_10G = 3,
+};
/* hw device description */
struct rnp_hw {
@@ -69,8 +98,18 @@ struct rnp_hw {
u16 vendor_id;
u16 max_vfs; /* device max support vf */
+ char device_name[RTE_DEV_NAME_MAX_LEN];
+
+ u8 max_port_num; /* max sub port of this nic */
+ u8 lane_mask; /* lane enabled bit */
+ u8 nic_mode;
u16 pf_vf_num;
+ /* hardware port sequence info */
+ u8 phy_port_ids[RNP_MAX_PORT_OF_PF]; /* port id: for lane0~3: value:0 ~ 7*/
+ u8 lane_of_port[RNP_MAX_PORT_OF_PF]; /* lane_id: hw lane map port 1:0 0:1 or 0:0 1:1 */
+ bool lane_is_sgmii[RNP_MAX_PORT_OF_PF];
struct rnp_mbx_info mbx;
+ struct rnp_fw_info fw_info;
};
#endif /* __RNP_H__*/
diff --git a/drivers/net/rnp/base/rnp_mac.c b/drivers/net/rnp/base/rnp_mac.c
new file mode 100644
index 0000000..b063f4c
--- /dev/null
+++ b/drivers/net/rnp/base/rnp_mac.c
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Mucse IC Design Ltd.
+ */
+
+#include "rnp_osdep.h"
+
+#include "rnp_mbx_fw.h"
+#include "rnp_mac.h"
+#include "../rnp.h"
+
+const struct rnp_mac_ops rnp_mac_ops_pf = {
+ .get_macaddr = rnp_mbx_fw_get_macaddr,
+};
+
+int rnp_get_mac_addr(struct rnp_eth_port *port, u8 *mac)
+{
+ const struct rnp_mac_ops *mac_ops =
+ RNP_DEV_PP_TO_MAC_OPS(port->eth_dev);
+
+ return rnp_call_hwif_impl(port, mac_ops->get_macaddr, mac);
+}
+
+void rnp_mac_ops_init(struct rnp_hw *hw)
+{
+ struct rnp_proc_priv *proc_priv = RNP_DEV_TO_PROC_PRIV(hw->back->eth_dev);
+
+ proc_priv->mac_ops = &rnp_mac_ops_pf;
+}
diff --git a/drivers/net/rnp/base/rnp_mac.h b/drivers/net/rnp/base/rnp_mac.h
new file mode 100644
index 0000000..8a12aa4
--- /dev/null
+++ b/drivers/net/rnp/base/rnp_mac.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Mucse IC Design Ltd.
+ */
+
+#ifndef _RNP_MAC_H_
+#define _RNP_MAC_H_
+
+#include "rnp_osdep.h"
+#include "rnp_hw.h"
+
+void rnp_mac_ops_init(struct rnp_hw *hw);
+int rnp_get_mac_addr(struct rnp_eth_port *port, u8 *mac);
+
+#endif /* _RNP_MAC_H_ */
diff --git a/drivers/net/rnp/base/rnp_mbx_fw.c b/drivers/net/rnp/base/rnp_mbx_fw.c
new file mode 100644
index 0000000..6c6f713
--- /dev/null
+++ b/drivers/net/rnp/base/rnp_mbx_fw.c
@@ -0,0 +1,338 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Mucse IC Design Ltd.
+ */
+
+#include <string.h>
+
+#include "rnp_mbx_fw.h"
+#include "rnp_fw_cmd.h"
+#include "rnp_mbx.h"
+#include "../rnp.h"
+
+#define RNP_MBX_API_MAX_RETRY (10)
+#define RNP_POLL_WAIT_MS (10)
+
+static int rnp_mbx_fw_post_req(struct rnp_eth_port *port,
+ struct rnp_mbx_fw_cmd_req *req,
+ struct rnp_mbx_req_cookie *cookie)
+{
+ const struct rnp_mbx_ops *ops = RNP_DEV_PP_TO_MBX_OPS(port->eth_dev);
+ struct rnp_hw *hw = port->hw;
+ u32 timeout_cnt;
+ int err = 0;
+
+ cookie->done = 0;
+
+ spin_lock(&hw->fw_info.fw_lock);
+
+ /* down_interruptible(&pf_cpu_lock); */
+ err = ops->write(hw, (u32 *)req,
+ (req->datalen + RNP_MBX_REQ_HDR_LEN) / 4, RNP_MBX_FW);
+ if (err) {
+ RNP_PMD_LOG(ERR, "rnp_write_mbx failed!\n");
+ goto quit;
+ }
+
+ timeout_cnt = cookie->timeout_ms / RNP_POLL_WAIT_MS;
+ while (timeout_cnt > 0) {
+ mdelay(RNP_POLL_WAIT_MS);
+ timeout_cnt--;
+ if (cookie->done)
+ break;
+ }
+quit:
+ spin_unlock(&hw->fw_info.fw_lock);
+ return err;
+}
+
+static int
+rnp_fw_send_cmd_wait(struct rnp_eth_port *port,
+ struct rnp_mbx_fw_cmd_req *req,
+ struct rnp_mbx_fw_cmd_reply *reply)
+{
+ const struct rnp_mbx_ops *ops = RNP_DEV_PP_TO_MBX_OPS(port->eth_dev);
+ struct rnp_hw *hw = port->hw;
+ u16 try_count = 0;
+ int err = 0;
+
+ if (ops == NULL || ops->write_posted == NULL)
+ return -EINVAL;
+ spin_lock(&hw->fw_info.fw_lock);
+ err = ops->write_posted(hw, (u32 *)req,
+ (req->datalen + RNP_MBX_REQ_HDR_LEN) / 4, RNP_MBX_FW);
+ if (err) {
+ RNP_PMD_LOG(ERR, "%s: write_posted failed!"
+ " err:0x%x", __func__, err);
+ spin_unlock(&hw->fw_info.fw_lock);
+ return err;
+ }
+ /* ignore non target information */
+fw_api_try:
+ err = ops->read_posted(hw, (u32 *)reply,
+ sizeof(*reply) / 4, RNP_MBX_FW);
+ if (err) {
+ RNP_PMD_LOG(ERR,
+ "%s: read_posted failed! err:0x%x"
+ " req-op:0x%x",
+ __func__,
+ err,
+ req->opcode);
+ goto err_quit;
+ }
+ if (req->opcode != reply->opcode) {
+ try_count++;
+ if (try_count < RNP_MBX_API_MAX_RETRY)
+ goto fw_api_try;
+ RNP_PMD_LOG(ERR,
+ "%s: read reply msg failed! err:0x%x"
+ " req-op:0x%x",
+ __func__,
+ err,
+ req->opcode);
+ err = -EIO;
+ }
+ if (reply->error_code) {
+ RNP_PMD_LOG(ERR,
+ "%s: reply err:0x%x. req-op:0x%x\n",
+ __func__,
+ reply->error_code,
+ req->opcode);
+ err = -reply->error_code;
+ goto err_quit;
+ }
+ spin_unlock(&hw->fw_info.fw_lock);
+
+ return err;
+err_quit:
+
+ spin_unlock(&hw->fw_info.fw_lock);
+ RNP_PMD_LOG(ERR,
+ "%s:PF[%d]: req:%08x_%08x_%08x_%08x "
+ "reply:%08x_%08x_%08x_%08x",
+ __func__,
+ hw->mbx.pf_num,
+ ((int *)req)[0],
+ ((int *)req)[1],
+ ((int *)req)[2],
+ ((int *)req)[3],
+ ((int *)reply)[0],
+ ((int *)reply)[1],
+ ((int *)reply)[2],
+ ((int *)reply)[3]);
+
+ return err;
+}
+
+static int
+rnp_fw_send_norep_cmd(struct rnp_eth_port *port,
+ struct rnp_fw_req_arg *arg)
+{
+ const struct rnp_mbx_ops *ops = RNP_DEV_PP_TO_MBX_OPS(port->eth_dev);
+ struct rnp_mbx_fw_cmd_req req;
+ struct rnp_hw *hw = port->hw;
+ int err = 0;
+
+ if (ops == NULL || ops->write_posted == NULL)
+ return -EINVAL;
+ memset(&req, 0, sizeof(req));
+ spin_lock(&hw->fw_info.fw_lock);
+ rnp_build_fwcmd_req(&req, arg, &req);
+ err = ops->write_posted(hw, (u32 *)&req,
+ (req.datalen + RNP_MBX_REQ_HDR_LEN) / 4, RNP_MBX_FW);
+ if (err) {
+ RNP_PMD_LOG(ERR, "%s: write_posted failed!"
+ " err:0x%x", __func__, err);
+ spin_unlock(&hw->fw_info.fw_lock);
+ return err;
+ }
+ spin_unlock(&hw->fw_info.fw_lock);
+
+ return 0;
+}
+
+static int
+rnp_fw_send_cmd(struct rnp_eth_port *port,
+ struct rnp_fw_req_arg *arg,
+ void *respond)
+{
+ struct rnp_mbx_req_cookie *cookie;
+ struct rnp_mbx_fw_cmd_reply reply;
+ struct rnp_mbx_fw_cmd_req req;
+ struct rnp_hw *hw = port->hw;
+ int err = 0;
+
+ memset(&req, 0, sizeof(req));
+ memset(&reply, 0, sizeof(reply));
+ if (hw->fw_info.fw_irq_en) {
+ cookie = rnp_dma_mem_alloc(hw, &hw->fw_info.mem,
+ sizeof(*cookie), hw->fw_info.cookie_name);
+ if (!cookie)
+ return -ENOMEM;
+ memset(cookie->priv, 0, cookie->priv_len);
+ rnp_build_fwcmd_req(&req, arg, cookie);
+ err = rnp_mbx_fw_post_req(port, &req, cookie);
+ if (err)
+ return err;
+ if (respond)
+ memcpy(respond, cookie->priv, RNP_FW_REP_DATA_NUM);
+ } else {
+ rnp_build_fwcmd_req(&req, arg, &req);
+ err = rnp_fw_send_cmd_wait(port, &req, &reply);
+ if (err)
+ return err;
+ if (respond)
+ memcpy(respond, reply.data, RNP_FW_REP_DATA_NUM);
+ }
+
+ return 0;
+}
+
+int rnp_fw_init(struct rnp_hw *hw)
+{
+ struct rnp_fw_info *fw_info = &hw->fw_info;
+ struct rnp_mbx_req_cookie *cookie = NULL;
+
+ snprintf(fw_info->cookie_name, RTE_MEMZONE_NAMESIZE,
+ "fw_req_cookie_%s",
+ hw->device_name);
+ fw_info->cookie_pool = rnp_dma_mem_alloc(hw, &fw_info->mem,
+ sizeof(struct rnp_mbx_req_cookie),
+ fw_info->cookie_name);
+ cookie = (struct rnp_mbx_req_cookie *)fw_info->cookie_pool;
+ if (cookie == NULL)
+ return -ENOMEM;
+ cookie->timeout_ms = 1000;
+ cookie->magic = RNP_COOKIE_MAGIC;
+ cookie->priv_len = RNP_MAX_SHARE_MEM;
+ spin_lock_init(&fw_info->fw_lock);
+ fw_info->fw_irq_en = false;
+
+ return 0;
+}
+
+static int
+rnp_fw_get_phy_capability(struct rnp_eth_port *port,
+ struct rnp_phy_abilities_rep *abil)
+{
+ u8 data[RNP_FW_REP_DATA_NUM] = {0};
+ struct rnp_fw_req_arg arg;
+ int err;
+
+ RTE_BUILD_BUG_ON(sizeof(*abil) != RNP_FW_REP_DATA_NUM);
+
+ memset(&arg, 0, sizeof(arg));
+ arg.opcode = RNP_GET_PHY_ABALITY;
+ err = rnp_fw_send_cmd(port, &arg, &data);
+ if (err)
+ return err;
+ memcpy(abil, &data, sizeof(*abil));
+
+ return 0;
+}
+
+int rnp_mbx_fw_get_capability(struct rnp_eth_port *port)
+{
+ struct rnp_phy_abilities_rep ablity;
+ struct rnp_hw *hw = port->hw;
+ u32 is_sgmii_bits = 0;
+ bool is_sgmii = false;
+ u16 lane_bit = 0;
+ u32 lane_cnt = 0;
+ int err = -EIO;
+ u16 temp_mask;
+ u8 lane_idx;
+ u8 idx;
+
+ memset(&ablity, 0, sizeof(ablity));
+ err = rnp_fw_get_phy_capability(port, &ablity);
+ if (!err) {
+ hw->lane_mask = ablity.lane_mask;
+ hw->nic_mode = ablity.nic_mode;
+ /* get phy<->lane mapping info */
+ lane_cnt = __builtin_popcount(hw->lane_mask);
+ temp_mask = hw->lane_mask;
+ if (ablity.e.ports_is_sgmii_valid)
+ is_sgmii_bits = ablity.e.lane_is_sgmii;
+ is_sgmii_bits = ablity.e.lane_is_sgmii;
+ for (idx = 0; idx < lane_cnt; idx++) {
+ hw->phy_port_ids[idx] = ablity.port_ids[idx];
+ lane_bit = ffs(temp_mask) - 1;
+ lane_idx = ablity.port_ids[idx] % lane_cnt;
+ hw->lane_of_port[lane_idx] = lane_bit;
+ is_sgmii = lane_bit & is_sgmii_bits ? 1 : 0;
+ hw->lane_is_sgmii[lane_idx] = is_sgmii;
+ temp_mask &= ~RTE_BIT32(lane_bit);
+ }
+ hw->max_port_num = lane_cnt;
+ }
+ if (lane_cnt <= 0 || lane_cnt > 4)
+ return -EIO;
+
+ RNP_PMD_LOG(INFO,
+ "%s: nic-mode:%d lane_cnt:%d lane_mask:0x%x"
+ " pfvfnum:0x%x, fw_version:0x%08x,"
+ " ports:%d-%d-%d-%d ncsi_en:%d\n",
+ __func__,
+ hw->nic_mode,
+ lane_cnt,
+ hw->lane_mask,
+ hw->pf_vf_num,
+ ablity.fw_version,
+ ablity.port_ids[0],
+ ablity.port_ids[1],
+ ablity.port_ids[2],
+ ablity.port_ids[3],
+ ablity.e.ncsi_en);
+
+ return err;
+}
+
+int rnp_mbx_fw_reset_phy(struct rnp_hw *hw)
+{
+ struct rnp_eth_port *port = RNP_DEV_TO_PORT(hw->back->eth_dev);
+ struct rnp_fw_req_arg arg;
+ int err;
+
+ memset(&arg, 0, sizeof(arg));
+ arg.opcode = RNP_RESET_PHY;
+ err = rnp_fw_send_norep_cmd(port, &arg);
+ if (err) {
+ RNP_PMD_LOG(ERR, "%s: failed. err:%d", __func__, err);
+ return err;
+ }
+
+ return 0;
+}
+
+int
+rnp_mbx_fw_get_macaddr(struct rnp_eth_port *port,
+ u8 *mac_addr)
+{
+ u8 data[RNP_FW_REP_DATA_NUM] = {0};
+ u32 nr_lane = port->attr.nr_lane;
+ struct rnp_mac_addr_rep *mac;
+ struct rnp_fw_req_arg arg;
+ int err;
+
+ if (!mac_addr)
+ return -EINVAL;
+ RTE_BUILD_BUG_ON(sizeof(*mac) != RNP_FW_REP_DATA_NUM);
+ memset(&arg, 0, sizeof(arg));
+ mac = (struct rnp_mac_addr_rep *)&data;
+ arg.opcode = RNP_GET_MAC_ADDRESS;
+ arg.param0 = nr_lane;
+ arg.param1 = port->hw->pf_vf_num;
+
+ err = rnp_fw_send_cmd(port, &arg, &data);
+ if (err) {
+ RNP_PMD_LOG(ERR, "%s: failed. err:%d\n", __func__, err);
+ return err;
+ }
+ if (RTE_BIT32(nr_lane) & mac->lanes) {
+ memcpy(mac_addr, mac->addrs[nr_lane].mac, 6);
+
+ return 0;
+ }
+
+ return -ENODATA;
+}
diff --git a/drivers/net/rnp/base/rnp_mbx_fw.h b/drivers/net/rnp/base/rnp_mbx_fw.h
new file mode 100644
index 0000000..255d913
--- /dev/null
+++ b/drivers/net/rnp/base/rnp_mbx_fw.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Mucse IC Design Ltd.
+ */
+
+#ifndef _RNP_MBX_FW_H_
+#define _RNP_MBX_FW_H_
+
+#include "rnp_osdep.h"
+#include "rnp_hw.h"
+
+struct rnp_eth_port;
+
+int rnp_mbx_fw_get_macaddr(struct rnp_eth_port *port, u8 *mac_addr);
+int rnp_mbx_fw_get_capability(struct rnp_eth_port *port);
+int rnp_mbx_fw_reset_phy(struct rnp_hw *hw);
+int rnp_fw_init(struct rnp_hw *hw);
+
+#endif /* _RNP_MBX_FW_H_ */
diff --git a/drivers/net/rnp/base/rnp_osdep.h b/drivers/net/rnp/base/rnp_osdep.h
index b0b3f34..3f31f9b 100644
--- a/drivers/net/rnp/base/rnp_osdep.h
+++ b/drivers/net/rnp/base/rnp_osdep.h
@@ -11,26 +11,57 @@
#include <rte_io.h>
#include <rte_log.h>
+#include <rte_bitops.h>
#include <rte_cycles.h>
+#include <rte_byteorder.h>
+#include <rte_common.h>
+#include <rte_memcpy.h>
+#include <rte_memzone.h>
+#include <rte_memory.h>
+#include <rte_dev.h>
#include "../rnp_logs.h"
typedef uint8_t u8;
+typedef int8_t s8;
typedef uint16_t u16;
typedef uint32_t u32;
+typedef uint64_t u64;
+
+typedef rte_iova_t dma_addr_t;
#define mb() rte_mb()
#define wmb() rte_wmb()
#define udelay(x) rte_delay_us(x)
+#define mdelay(x) rte_delay_ms(x)
+#define memcpy rte_memcpy
+
+#define spinlock_t rte_spinlock_t
+#define spin_lock_init(spinlock_v) rte_spinlock_init(spinlock_v)
+#define spin_lock(spinlock_v) rte_spinlock_lock(spinlock_v)
+#define spin_unlock(spinlock_v) rte_spinlock_unlock(spinlock_v)
+#define _ETH_(off) ((off) + (0x10000))
+#define _NIC_(off) ((off) + (0x30000))
#define _MSI_(off) ((off) + (0xA0000))
+#ifndef _PACKED_ALIGN4
+#define _PACKED_ALIGN4 __attribute__((packed, aligned(4)))
+#endif
+
+#if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
+ #error "__BIG_ENDIAN is not support now."
+#endif
+
+#define FALSE 0
+#define TRUE 1
+
#define __iomem
static inline u32
-rnp_reg_read32(void *base, size_t offset)
+rnp_reg_read32(volatile void *base, size_t offset)
{
- unsigned int v = rte_read32(((u8 *)base + offset));
+ unsigned int v = rte_read32(((volatile u8 *)base + offset));
RNP_PMD_REG_LOG(DEBUG, "offset=0x%08lx val=0x%04x",
(unsigned long)offset, v);
@@ -38,15 +69,74 @@
}
static inline void
-rnp_reg_write32(void *base, size_t offset, u32 val)
+rnp_reg_write32(volatile void *base, size_t offset, u32 val)
{
RNP_PMD_REG_LOG(DEBUG, "offset=0x%08lx val=0x%08x",
(unsigned long)offset, val);
- rte_write32(val, ((u8 *)base + offset));
+ rte_write32(val, ((volatile u8 *)base + offset));
+}
+
+struct rnp_dma_mem {
+ void *va;
+ dma_addr_t pa;
+ u32 size;
+ const void *mz;
+};
+
+struct rnp_hw;
+
+static inline void *
+rnp_dma_mem_alloc(__rte_unused struct rnp_hw *hw,
+ struct rnp_dma_mem *mem, u64 size, const char *name)
+{
+ static RTE_ATOMIC(uint64_t) rnp_dma_memzone_id;
+ const struct rte_memzone *mz = NULL;
+ char z_name[RTE_MEMZONE_NAMESIZE];
+
+ if (!mem)
+ return NULL;
+ if (name) {
+ strcpy(z_name, name);
+ mz = rte_memzone_lookup((const char *)z_name);
+ if (mz)
+ return mem->va;
+ } else {
+ snprintf(z_name, sizeof(z_name), "rnp_dma_%" PRIu64,
+ rte_atomic_fetch_add_explicit(&rnp_dma_memzone_id, 1,
+ rte_memory_order_relaxed));
+ }
+ mz = rte_memzone_reserve_bounded(z_name, size, SOCKET_ID_ANY, 0,
+ 0, RTE_PGSIZE_2M);
+ if (!mz)
+ return NULL;
+
+ mem->size = size;
+ mem->va = mz->addr;
+ mem->pa = mz->iova;
+ mem->mz = (const void *)mz;
+ RNP_PMD_DRV_LOG(DEBUG, "memzone %s allocated with physical address: "
+ "%"PRIu64, mz->name, mem->pa);
+
+ return mem->va;
+}
+
+static inline void
+rnp_dma_mem_free(__rte_unused struct rnp_hw *hw,
+ struct rnp_dma_mem *mem)
+{
+ RNP_PMD_DRV_LOG(DEBUG, "memzone %s to be freed with physical address: "
+ "%"PRIu64, ((const struct rte_memzone *)mem->mz)->name,
+ mem->pa);
+ if (mem->mz) {
+ rte_memzone_free((const struct rte_memzone *)mem->mz);
+ mem->mz = NULL;
+ mem->va = NULL;
+ mem->pa = (dma_addr_t)0;
+ }
}
#define RNP_REG_RD(base, offset) rnp_reg_read32(base, offset)
-#define RNP_REG_WR(base, offset) rnp_reg_write32(base, offset)
+#define RNP_REG_WR(base, offset, val) rnp_reg_write32(base, offset, val)
#define RNP_E_REG_WR(hw, off, value) rnp_reg_write32((hw)->e_ctrl, (off), (value))
#define RNP_E_REG_RD(hw, off) rnp_reg_read32((hw)->e_ctrl, (off))
diff --git a/drivers/net/rnp/meson.build b/drivers/net/rnp/meson.build
index d6cb380..29e6d49 100644
--- a/drivers/net/rnp/meson.build
+++ b/drivers/net/rnp/meson.build
@@ -9,6 +9,7 @@ endif
subdir('base')
objs = [base_objs]
+deps += ['net']
includes += include_directories('base')
sources = files(
diff --git a/drivers/net/rnp/rnp.h b/drivers/net/rnp/rnp.h
index 904b7ad..0b33d5b 100644
--- a/drivers/net/rnp/rnp.h
+++ b/drivers/net/rnp/rnp.h
@@ -13,20 +13,60 @@
#define RNP_DEV_ID_N10G (0x1000)
#define RNP_MAX_VF_NUM (64)
#define RNP_MISC_VEC_ID RTE_INTR_VEC_ZERO_OFFSET
+/* maximum frame size supported */
+#define RNP_MAC_MAXFRM_SIZE (9590)
+
+struct rnp_port_attr {
+ uint16_t max_mac_addrs; /* max support mac address */
+ uint16_t port_id; /* platform manage port sequence id */
+ uint8_t port_offset; /* port queue offset */
+ uint8_t sw_id; /* software port init sequence id */
+ uint16_t nr_lane; /* phy lane of This PF:0~3 */
+};
struct rnp_proc_priv {
+ const struct rnp_mac_ops *mac_ops;
const struct rnp_mbx_ops *mbx_ops;
};
struct rnp_eth_port {
+ struct rnp_proc_priv *proc_priv;
+ struct rte_ether_addr mac_addr;
+ struct rte_eth_dev *eth_dev;
+ struct rnp_port_attr attr;
+ struct rnp_hw *hw;
};
struct rnp_eth_adapter {
struct rnp_hw hw;
+ struct rte_pci_device *pdev;
struct rte_eth_dev *eth_dev; /* alloc eth_dev by platform */
+
+ struct rnp_eth_port *ports[RNP_MAX_PORT_OF_PF];
+ uint16_t closed_ports;
+ uint16_t inited_ports;
+ bool intr_registed;
};
+#define RNP_DEV_TO_PORT(eth_dev) \
+ ((struct rnp_eth_port *)(eth_dev)->data->dev_private)
+#define RNP_DEV_TO_ADAPTER(eth_dev) \
+ ((struct rnp_eth_adapter *)(RNP_DEV_TO_PORT(eth_dev))->hw->back)
#define RNP_DEV_TO_PROC_PRIV(eth_dev) \
((struct rnp_proc_priv *)(eth_dev)->process_private)
+#define RNP_DEV_PP_TO_MBX_OPS(priv) \
+ (((RNP_DEV_TO_PROC_PRIV(priv))->mbx_ops))
+#define RNP_DEV_PP_TO_MAC_OPS(priv) \
+ (((RNP_DEV_TO_PROC_PRIV(priv))->mac_ops))
+
+#define RNP_PF_OWN_PORTS(id) (((id) == 0) ? 1 : (((id) == 1) ? 2 : 4))
+
+static inline int
+rnp_pf_is_multiple_ports(uint32_t device_id)
+{
+ uint32_t verbit = (device_id >> 5) & 0x3;
+
+ return RNP_PF_OWN_PORTS(verbit) == 1 ? 0 : 1;
+}
#endif /* __RNP_H__ */
diff --git a/drivers/net/rnp/rnp_ethdev.c b/drivers/net/rnp/rnp_ethdev.c
index 389c6ad..ae417a6 100644
--- a/drivers/net/rnp/rnp_ethdev.c
+++ b/drivers/net/rnp/rnp_ethdev.c
@@ -3,39 +3,340 @@
*/
#include <ethdev_pci.h>
+#include <ethdev_driver.h>
#include <rte_io.h>
#include <rte_malloc.h>
#include "rnp.h"
+#include "rnp_logs.h"
+#include "base/rnp_mbx.h"
+#include "base/rnp_mbx_fw.h"
+#include "base/rnp_mac.h"
+#include "base/rnp_common.h"
+
+static struct rte_eth_dev *
+rnp_alloc_eth_port(struct rte_pci_device *pci, char *name)
+{
+ struct rte_eth_dev *eth_dev = NULL;
+ struct rnp_eth_port *port = NULL;
+
+ eth_dev = rte_eth_dev_allocate(name);
+ if (!eth_dev) {
+ RNP_PMD_ERR("Could not allocate eth_dev for %s", name);
+ return NULL;
+ }
+ port = rte_zmalloc_socket(name,
+ sizeof(*port),
+ RTE_CACHE_LINE_SIZE,
+ pci->device.numa_node);
+ if (!port) {
+ RNP_PMD_ERR("Could not allocate rnp_eth_port for %s", name);
+ goto fail_calloc;
+ }
+ rte_eth_copy_pci_info(eth_dev, pci);
+ eth_dev->data->dev_private = port;
+ eth_dev->device = &pci->device;
+
+ return eth_dev;
+fail_calloc:
+ rte_free(port);
+ rte_eth_dev_release_port(eth_dev);
+
+ return NULL;
+}
+
+static void rnp_dev_interrupt_handler(void *param)
+{
+ RTE_SET_USED(param);
+}
+
+static int rnp_dev_stop(struct rte_eth_dev *eth_dev)
+{
+ RTE_SET_USED(eth_dev);
+
+ return 0;
+}
+
+static int rnp_dev_close(struct rte_eth_dev *eth_dev)
+{
+ struct rnp_eth_adapter *adapter = RNP_DEV_TO_ADAPTER(eth_dev);
+ struct rte_pci_device *pci_dev;
+ int ret = 0;
+
+ PMD_INIT_FUNC_TRACE();
+
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return 0;
+ ret = rnp_dev_stop(eth_dev);
+ if (ret < 0)
+ return ret;
+ if (adapter->closed_ports == adapter->inited_ports) {
+ pci_dev = RTE_DEV_TO_PCI(eth_dev->device);
+ if (adapter->intr_registed) {
+ /* disable uio intr before callback unregister */
+ rte_intr_disable(pci_dev->intr_handle);
+ rte_intr_callback_unregister(pci_dev->intr_handle,
+ rnp_dev_interrupt_handler,
+ (void *)eth_dev);
+ adapter->intr_registed = false;
+ }
+ rnp_dma_mem_free(&adapter->hw, &adapter->hw.fw_info.mem);
+ rte_free(adapter);
+ }
+ adapter->closed_ports++;
+
+ return 0;
+}
+
+/* Features supported by this driver */
+static const struct eth_dev_ops rnp_eth_dev_ops = {
+ .dev_close = rnp_dev_close,
+ .dev_stop = rnp_dev_stop,
+};
+
+static void
+rnp_setup_port_attr(struct rnp_eth_port *port,
+ struct rte_eth_dev *eth_dev,
+ uint8_t sw_id)
+{
+ struct rnp_port_attr *attr = &port->attr;
+ struct rnp_hw *hw = port->hw;
+ uint32_t lane;
+
+ PMD_INIT_FUNC_TRACE();
+
+ lane = hw->phy_port_ids[sw_id] & (hw->max_port_num - 1);
+ attr->port_id = eth_dev->data->port_id;
+ attr->port_offset = RNP_E_REG_RD(hw, RNP_TC_PORT_OFFSET(lane));
+ attr->nr_lane = lane;
+ attr->sw_id = sw_id;
+ attr->max_mac_addrs = 1;
+
+ RNP_PMD_INFO("PF[%d] SW-ETH-PORT[%d]<->PHY_LANE[%d]\n",
+ hw->mbx.pf_num, sw_id, lane);
+}
+
+static int
+rnp_init_port_resource(struct rnp_eth_adapter *adapter,
+ struct rte_eth_dev *eth_dev,
+ char *name,
+ uint8_t p_id)
+{
+ struct rnp_eth_port *port = RNP_DEV_TO_PORT(eth_dev);
+ struct rte_pci_device *pci_dev = adapter->pdev;
+ char mac_str[RTE_ETHER_ADDR_FMT_SIZE] = " ";
+
+ PMD_INIT_FUNC_TRACE();
+
+ port->eth_dev = eth_dev;
+ port->hw = &adapter->hw;
+
+ eth_dev->dev_ops = &rnp_eth_dev_ops;
+ eth_dev->device = &pci_dev->device;
+ eth_dev->data->mtu = RTE_ETHER_MTU;
+
+ rnp_setup_port_attr(port, eth_dev, p_id);
+ eth_dev->data->mac_addrs = rte_zmalloc(name,
+ sizeof(struct rte_ether_addr) *
+ port->attr.max_mac_addrs, 0);
+ if (!eth_dev->data->mac_addrs) {
+ RNP_PMD_ERR("zmalloc for mac failed! Exiting.");
+ return -ENOMEM;
+ }
+ rnp_get_mac_addr(port, port->mac_addr.addr_bytes);
+ rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
+ &port->mac_addr);
+ RNP_PMD_INFO("get mac addr from firmware %s\n", mac_str);
+ if (!rte_is_valid_assigned_ether_addr(&port->mac_addr)) {
+ RNP_PMD_WARN("get mac_addr is invalid, just use random");
+ rte_eth_random_addr(port->mac_addr.addr_bytes);
+ }
+ rte_ether_addr_copy(&port->mac_addr, ð_dev->data->mac_addrs[0]);
+
+ adapter->ports[p_id] = port;
+ adapter->inited_ports++;
+
+ return 0;
+}
+
+static int
+rnp_proc_priv_init(struct rte_eth_dev *dev)
+{
+ struct rnp_proc_priv *priv;
+
+ priv = rte_zmalloc_socket("rnp_proc_priv",
+ sizeof(struct rnp_proc_priv),
+ RTE_CACHE_LINE_SIZE,
+ dev->device->numa_node);
+ if (!priv)
+ return -ENOMEM;
+ dev->process_private = priv;
+
+ return 0;
+}
static int
rnp_eth_dev_init(struct rte_eth_dev *eth_dev)
{
- RTE_SET_USED(eth_dev);
+ struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
+ struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
+ struct rnp_eth_port *port = RNP_DEV_TO_PORT(eth_dev);
+ char name[RTE_ETH_NAME_MAX_LEN] = " ";
+ struct rnp_eth_adapter *adapter;
+ struct rte_eth_dev *sub_eth_dev;
+ struct rnp_hw *hw;
+ uint16_t p_id;
+ int ret = -1;
+
+ PMD_INIT_FUNC_TRACE();
- return -ENODEV;
+ snprintf(name, sizeof(name), "rnp_adapter_%d", eth_dev->data->port_id);
+ adapter = rte_zmalloc(name, sizeof(struct rnp_eth_adapter), 0);
+ if (!adapter) {
+ RNP_PMD_ERR("rnp_adapter zmalloc mem failed");
+ return -ENOMEM;
+ }
+ hw = &adapter->hw;
+ adapter->pdev = pci_dev;
+ adapter->eth_dev = eth_dev;
+ adapter->ports[0] = port;
+ hw->back = (void *)adapter;
+ port->eth_dev = eth_dev;
+ port->hw = hw;
+
+ hw->e_ctrl = (u8 *)pci_dev->mem_resource[4].addr;
+ hw->c_ctrl = (u8 *)pci_dev->mem_resource[0].addr;
+ hw->c_blen = pci_dev->mem_resource[0].len;
+ hw->device_id = pci_dev->id.device_id;
+ hw->vendor_id = pci_dev->id.vendor_id;
+ hw->mbx.en_vfs = pci_dev->max_vfs;
+ if (hw->mbx.en_vfs > hw->max_vfs) {
+ ret = -EINVAL;
+ RNP_PMD_ERR("sriov vfs max support 64");
+ goto free_ad;
+ }
+
+ strlcpy(hw->device_name, pci_dev->device.name,
+ strlen(pci_dev->device.name) + 1);
+ ret = rnp_proc_priv_init(eth_dev);
+ if (ret < 0) {
+ RNP_PMD_ERR("proc_priv_alloc failed");
+ goto free_ad;
+ }
+ ret = rnp_init_mbx_pf(hw);
+ if (ret < 0) {
+ RNP_PMD_ERR("mailbox hardware init failed");
+ goto free_ad;
+ }
+ ret = rnp_init_hw(hw);
+ if (ret < 0) {
+ RNP_PMD_ERR("Hardware initialization failed");
+ goto free_ad;
+ }
+ ret = rnp_setup_common_ops(hw);
+ if (ret < 0) {
+ RNP_PMD_ERR("hardware common ops setup failed");
+ goto free_ad;
+ }
+ for (p_id = 0; p_id < hw->max_port_num; p_id++) {
+ /* port 0 resource has been allocated when probe */
+ if (!p_id) {
+ sub_eth_dev = eth_dev;
+ } else {
+ memset(name, 0, sizeof(name));
+ snprintf(name, sizeof(name),
+ "%s_%d", hw->device_name, p_id);
+ sub_eth_dev = rnp_alloc_eth_port(pci_dev, name);
+ if (!sub_eth_dev) {
+ RNP_PMD_ERR("%s sub_eth alloc failed",
+ hw->device_name);
+ ret = -ENOMEM;
+ goto eth_alloc_error;
+ }
+ ret = rnp_proc_priv_init(sub_eth_dev);
+ if (ret < 0) {
+ RNP_PMD_ERR("proc_priv_alloc failed");
+ goto eth_alloc_error;
+ }
+ rte_memcpy(sub_eth_dev->process_private,
+ eth_dev->process_private,
+ sizeof(struct rnp_proc_priv));
+ }
+ ret = rnp_init_port_resource(adapter, sub_eth_dev, name, p_id);
+ if (ret)
+ goto eth_alloc_error;
+ if (p_id) {
+ /* port 0 will be probe by plaform */
+ rte_eth_dev_probing_finish(sub_eth_dev);
+ }
+ }
+ /* enable link update event interrupt */
+ rte_intr_callback_register(intr_handle,
+ rnp_dev_interrupt_handler, adapter);
+ rte_intr_enable(intr_handle);
+ adapter->intr_registed = true;
+ hw->fw_info.fw_irq_en = true;
+
+ return 0;
+
+eth_alloc_error:
+ for (p_id = 0; p_id < adapter->inited_ports; p_id++) {
+ port = adapter->ports[p_id];
+ if (!port)
+ continue;
+ if (port->eth_dev) {
+ rnp_dev_close(port->eth_dev);
+ /* just release eth_dev alloced by myself */
+ if (port->eth_dev != adapter->eth_dev)
+ rte_eth_dev_release_port(port->eth_dev);
+ }
+ }
+free_ad:
+ if (hw->fw_info.cookie_pool)
+ rnp_dma_mem_free(hw, &hw->fw_info.mem);
+ rte_free(adapter);
+
+ return ret;
}
static int
rnp_eth_dev_uninit(struct rte_eth_dev *eth_dev)
{
- RTE_SET_USED(eth_dev);
+ struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
+ uint16_t port_id;
+ int err = 0;
+
+ /* Free up other ports and all resources */
+ RTE_ETH_FOREACH_DEV_OF(port_id, &pci_dev->device)
+ err |= rte_eth_dev_close(port_id);
- return -ENODEV;
+ return err == 0 ? 0 : -EIO;
}
static int
rnp_pci_remove(struct rte_pci_device *pci_dev)
{
+ char device_name[RTE_ETH_NAME_MAX_LEN] = "";
struct rte_eth_dev *eth_dev;
+ uint16_t idx = 0;
int rc;
- eth_dev = rte_eth_dev_allocated(pci_dev->device.name);
-
+ /* Find a port belong to pf that not be called dev_close */
+ for (idx = 0; idx < RNP_MAX_PORT_OF_PF; idx++) {
+ if (idx)
+ snprintf(device_name, sizeof(device_name), "%s_%d",
+ pci_dev->device.name,
+ idx);
+ else
+ snprintf(device_name, sizeof(device_name), "%s",
+ pci_dev->device.name);
+ eth_dev = rte_eth_dev_allocated(device_name);
+ if (eth_dev)
+ break;
+ }
if (eth_dev) {
/* Cleanup eth dev */
- rc = rte_eth_dev_pci_generic_remove(pci_dev,
- rnp_eth_dev_uninit);
+ rc = rnp_eth_dev_uninit(eth_dev);
if (rc)
return rc;
}
--
1.8.3.1
next prev parent reply other threads:[~2025-02-08 2:45 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-08 2:43 [PATCH v7 00/28] [v6]drivers/net Add Support mucse N10 Pmd Driver Wenbo Cao
2025-02-08 2:43 ` [PATCH v7 01/28] net/rnp: add skeleton Wenbo Cao
2025-02-08 2:43 ` [PATCH v7 02/28] net/rnp: add ethdev probe and remove Wenbo Cao
2025-02-08 2:43 ` [PATCH v7 03/28] net/rnp: add log Wenbo Cao
2025-02-08 2:43 ` [PATCH v7 04/28] net/rnp: support mailbox basic operate Wenbo Cao
2025-02-08 2:43 ` Wenbo Cao [this message]
2025-02-08 2:43 ` [PATCH v7 06/28] net/rnp: add get device information operation Wenbo Cao
2025-02-08 2:43 ` [PATCH v7 07/28] net/rnp: add support mac promisc mode Wenbo Cao
2025-02-08 2:43 ` [PATCH v7 08/28] net/rnp: add queue setup and release operations Wenbo Cao
2025-02-08 2:43 ` [PATCH v7 09/28] net/rnp: add queue stop and start operations Wenbo Cao
2025-02-08 2:43 ` [PATCH v7 10/28] net/rnp: add support device start stop operations Wenbo Cao
2025-02-08 2:43 ` [PATCH v7 11/28] net/rnp: add RSS support operations Wenbo Cao
2025-02-08 2:43 ` [PATCH v7 12/28] net/rnp: add support link update operations Wenbo Cao
2025-02-08 2:43 ` [PATCH v7 13/28] net/rnp: add support link setup operations Wenbo Cao
2025-02-08 2:43 ` [PATCH v7 14/28] net/rnp: add Rx burst simple support Wenbo Cao
2025-02-08 2:43 ` [PATCH v7 15/28] net/rnp: add Tx " Wenbo Cao
2025-02-08 2:43 ` [PATCH v7 16/28] net/rnp: add MTU set operation Wenbo Cao
2025-02-08 2:43 ` [PATCH v7 17/28] net/rnp: add Rx scatter segment version Wenbo Cao
2025-02-08 2:43 ` [PATCH v7 18/28] net/rnp: add Tx multiple " Wenbo Cao
2025-02-08 2:43 ` [PATCH v7 19/28] net/rnp: add support basic stats operation Wenbo Cao
2025-02-08 2:43 ` [PATCH v7 20/28] net/rnp: add support xstats operation Wenbo Cao
2025-02-08 2:43 ` [PATCH v7 21/28] net/rnp: add unicast MAC filter operation Wenbo Cao
2025-02-08 2:43 ` [PATCH v7 22/28] net/rnp: add supported packet types Wenbo Cao
2025-02-08 2:44 ` [PATCH v7 23/28] net/rnp: add support Rx checksum offload Wenbo Cao
2025-02-08 2:44 ` [PATCH v7 24/28] net/rnp: add support Tx TSO offload Wenbo Cao
2025-02-08 2:44 ` [PATCH v7 25/28] net/rnp: support VLAN offloads Wenbo Cao
2025-02-08 2:44 ` [PATCH v7 26/28] net/rnp: add support VLAN filters operations Wenbo Cao
2025-02-08 2:44 ` [PATCH v7 27/28] net/rnp: add queue info operation Wenbo Cao
2025-02-08 2:44 ` [PATCH v7 28/28] net/rnp: support Rx/Tx burst mode info Wenbo Cao
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1738982645-34550-6-git-send-email-caowenbo@mucse.com \
--to=caowenbo@mucse.com \
--cc=anatoly.burakov@intel.com \
--cc=andrew.rybchenko@oktetlabs.ru \
--cc=dev@dpdk.org \
--cc=ferruh.yigit@amd.com \
--cc=stephen@networkplumber.org \
--cc=thomas@monjalon.net \
--cc=yaojun@mucse.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).