From patchwork Wed Aug 2 08:11:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: 11 X-Patchwork-Id: 129828 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 9A06F42FB8; Wed, 2 Aug 2023 10:13:34 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 14A6E43272; Wed, 2 Aug 2023 10:13:02 +0200 (CEST) Received: from smtpbgeu1.qq.com (smtpbgeu1.qq.com [52.59.177.22]) by mails.dpdk.org (Postfix) with ESMTP id 1C80E410DC for ; Wed, 2 Aug 2023 10:12:59 +0200 (CEST) X-QQ-mid: bizesmtp91t1690963971t0mrs918 Received: from steven.localdomain ( [183.81.182.182]) by bizesmtp.qq.com (ESMTP) with id ; Wed, 02 Aug 2023 16:12:49 +0800 (CST) X-QQ-SSF: 01400000000000D0E000000B0000000 X-QQ-FEAT: ILHsT53NKPjK17DrTlfPYoY8zKkH8/zt8lDYkcIpXl9JQuAEgDVgFHL0z6PLX m2GB6dlPLyhsxLPnp4FxaFFdXGUI8k49fdNeX9Uq8/0ecUebMwnLlDABC/k0tjAo96QUzsv NdW50BV5v1rTozug0XXD3Sn0OVdVtOz94GHBIp5YJC8HcpoVCP1bc4gWUeClnAexUNFIBsw obPuFnMYf4DJSpuss2Cx3+xiJLY+n7w3U9uQ5jM3r67Ip1dTrJhTm5MqyWuHxsjfjeNv0Iz yrQTaFZ/K9Y04+4uYvY0pKtphmcZ9+N0fiU/W+rJqiKcQNmq5JcUPVCXN8ymtQCTxDczWDr Qt2uzZj+nf8HiiD4qPen6W9jgpt21Z0+EKD0AGpdveUFkg85u3TKEqz7a0kaMJd9BXM7YBB fynXyjxb0KQ= X-QQ-GoodBg: 2 X-BIZMAIL-ID: 5549650621257719348 From: Wenbo Cao To: Wenbo Cao Cc: dev@dpdk.org, ferruh.yigit@intel.com, andrew.rybchenko@oktetlabs.ru Subject: [PATCH v2 7/8] net/rnp add devargs runtime parsing functions Date: Wed, 2 Aug 2023 08:11:05 +0000 Message-Id: <20230802081106.2340406-8-caowenbo@mucse.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20230802081106.2340406-1-caowenbo@mucse.com> References: <20230802081106.2340406-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 add various runtime devargs command line options supported by this driver. Signed-off-by: Wenbo Cao --- drivers/net/rnp/rnp.h | 22 +++++ drivers/net/rnp/rnp_ethdev.c | 164 +++++++++++++++++++++++++++++++++++ drivers/net/rnp/rnp_mbx_fw.c | 164 +++++++++++++++++++++++++++++++++++ drivers/net/rnp/rnp_mbx_fw.h | 69 +++++++++++++++ 4 files changed, 419 insertions(+) diff --git a/drivers/net/rnp/rnp.h b/drivers/net/rnp/rnp.h index d0d91bf5e5..75789c02f4 100644 --- a/drivers/net/rnp/rnp.h +++ b/drivers/net/rnp/rnp.h @@ -107,6 +107,8 @@ struct rnp_eth_port { void *adapt; uint8_t mac_addr[RTE_ETHER_ADDR_LEN]; struct rnp_hw *hw; + uint8_t rx_func_sec; /* force set io rx_func */ + uint8_t tx_func_sec; /* force set io tx func */ struct rte_eth_dev *eth_dev; struct rnp_port_attr attr; /* Recvice Mac Address Record Table */ @@ -122,6 +124,13 @@ struct rnp_share_ops { const struct rnp_mac_api *mac_api; } __rte_cache_aligned; +enum { + RNP_IO_FUNC_USE_NONE = 0, + RNP_IO_FUNC_USE_VEC, + RNP_IO_FUNC_USE_SIMPLE, + RNP_IO_FUNC_USE_COMMON, +}; + struct rnp_eth_adapter { enum rnp_work_mode mode; enum rnp_resource_share_m s_mode; /* Port Resource Share Policy */ @@ -135,6 +144,19 @@ struct rnp_eth_adapter { int max_link_speed; uint8_t num_ports; /* Cur Pf Has physical Port Num */ uint8_t lane_mask; + + uint8_t rx_func_sec; /* force set io rx_func */ + uint8_t tx_func_sec; /* force set io tx func*/ + /*fw-update*/ + bool do_fw_update; + char *fw_path; + + bool loopback_en; + bool fw_sfp_10g_1g_auto_det; + int fw_force_speed_1g; +#define FOCE_SPEED_1G_NOT_SET (-1) +#define FOCE_SPEED_1G_DISABLED (0) +#define FOCE_SPEED_1G_ENABLED (1) } __rte_cache_aligned; #define RNP_DEV_TO_PORT(eth_dev) \ diff --git a/drivers/net/rnp/rnp_ethdev.c b/drivers/net/rnp/rnp_ethdev.c index 54f6779295..109557eb85 100644 --- a/drivers/net/rnp/rnp_ethdev.c +++ b/drivers/net/rnp/rnp_ethdev.c @@ -6,6 +6,7 @@ #include #include #include +#include #include "rnp.h" #include "rnp_api.h" @@ -14,6 +15,13 @@ #include "rnp_rxtx.h" #include "rnp_logs.h" +#define RNP_HW_MAC_LOOPBACK_ARG "hw_loopback" +#define RNP_FW_UPDATE "fw_update" +#define RNP_RX_FUNC_SELECT "rx_func_sec" +#define RNP_TX_FUNC_SELECT "tx_func_sec" +#define RNP_FW_4X10G_10G_1G_DET "fw_4x10g_10g_1g_auto_det" +#define RNP_FW_FORCE_SPEED_1G "fw_force_1g_speed" + static int rnp_mac_rx_disable(struct rte_eth_dev *dev) { @@ -108,6 +116,8 @@ rnp_init_port_resource(struct rnp_eth_adapter *adapter, struct rnp_hw *hw = &adapter->hw; port->adapt = adapter; + port->rx_func_sec = adapter->rx_func_sec; + port->tx_func_sec = adapter->tx_func_sec; port->s_mode = adapter->s_mode; port->port_stopped = 1; port->hw = hw; @@ -443,6 +453,152 @@ rnp_special_ops_init(struct rte_eth_dev *eth_dev) return 0; } +static const char *const rnp_valid_arguments[] = { + RNP_HW_MAC_LOOPBACK_ARG, + RNP_FW_UPDATE, + RNP_RX_FUNC_SELECT, + RNP_TX_FUNC_SELECT, + RNP_FW_4X10G_10G_1G_DET, + RNP_FW_FORCE_SPEED_1G, + NULL +}; + +static int +rnp_parse_handle_devarg(const char *key, const char *value, + void *extra_args) +{ + struct rnp_eth_adapter *adapter = NULL; + + if (value == NULL || extra_args == NULL) + return -EINVAL; + + if (strcmp(key, RNP_HW_MAC_LOOPBACK_ARG) == 0) { + uint16_t *n = extra_args; + *n = (uint16_t)strtoul(value, NULL, 10); + if (*n == USHRT_MAX && errno == ERANGE) + return -1; + } else if (strcmp(key, RNP_FW_UPDATE) == 0) { + adapter = (struct rnp_eth_adapter *)extra_args; + adapter->do_fw_update = true; + adapter->fw_path = strdup(value); + } else if (strcmp(key, RNP_FW_4X10G_10G_1G_DET) == 0) { + adapter = (struct rnp_eth_adapter *)extra_args; + if (adapter->num_ports == 2 && adapter->hw.speed == 10 * 1000) { + adapter->fw_sfp_10g_1g_auto_det = + (strcmp(value, "on") == 0) ? true : false; + } else { + adapter->fw_sfp_10g_1g_auto_det = false; + } + } else if (strcmp(key, RNP_FW_FORCE_SPEED_1G) == 0) { + adapter = (struct rnp_eth_adapter *)extra_args; + if (adapter->num_ports == 2) { + if (strcmp(value, "on") == 0) + adapter->fw_force_speed_1g = FOCE_SPEED_1G_ENABLED; + else if (strcmp(value, "off") == 0) + adapter->fw_force_speed_1g = FOCE_SPEED_1G_DISABLED; + } + } else { + return -1; + } + + return 0; +} + +static int +rnp_parse_io_select_func(const char *key, const char *value, void *extra_args) +{ + uint8_t select = RNP_IO_FUNC_USE_NONE; + + RTE_SET_USED(key); + + if (strcmp(value, "vec") == 0) + select = RNP_IO_FUNC_USE_VEC; + else if (strcmp(value, "simple") == 0) + select = RNP_IO_FUNC_USE_SIMPLE; + else if (strcmp(value, "common") == 0) + select = RNP_IO_FUNC_USE_COMMON; + + *(uint8_t *)extra_args = select; + + return 0; +} + +static int +rnp_parse_devargs(struct rnp_eth_adapter *adapter, + struct rte_devargs *devargs) +{ + uint8_t rx_io_func = RNP_IO_FUNC_USE_NONE; + uint8_t tx_io_func = RNP_IO_FUNC_USE_NONE; + struct rte_kvargs *kvlist; + bool loopback_en = false; + int ret = 0; + + adapter->do_fw_update = false; + adapter->fw_sfp_10g_1g_auto_det = false; + adapter->fw_force_speed_1g = FOCE_SPEED_1G_NOT_SET; + + if (!devargs) + goto def; + + kvlist = rte_kvargs_parse(devargs->args, rnp_valid_arguments); + if (kvlist == NULL) + goto def; + + if (rte_kvargs_count(kvlist, RNP_HW_MAC_LOOPBACK_ARG) == 1) + ret = rte_kvargs_process(kvlist, RNP_HW_MAC_LOOPBACK_ARG, + &rnp_parse_handle_devarg, &loopback_en); + + if (rte_kvargs_count(kvlist, RNP_FW_4X10G_10G_1G_DET) == 1) + ret = rte_kvargs_process(kvlist, + RNP_FW_4X10G_10G_1G_DET, + &rnp_parse_handle_devarg, + adapter); + + if (rte_kvargs_count(kvlist, RNP_FW_FORCE_SPEED_1G) == 1) + ret = rte_kvargs_process(kvlist, + RNP_FW_FORCE_SPEED_1G, + &rnp_parse_handle_devarg, + adapter); + + if (rte_kvargs_count(kvlist, RNP_FW_UPDATE) == 1) + ret = rte_kvargs_process(kvlist, RNP_FW_UPDATE, + &rnp_parse_handle_devarg, adapter); + if (rte_kvargs_count(kvlist, RNP_RX_FUNC_SELECT) == 1) + ret = rte_kvargs_process(kvlist, RNP_RX_FUNC_SELECT, + &rnp_parse_io_select_func, &rx_io_func); + if (rte_kvargs_count(kvlist, RNP_TX_FUNC_SELECT) == 1) + ret = rte_kvargs_process(kvlist, RNP_TX_FUNC_SELECT, + &rnp_parse_io_select_func, &tx_io_func); + rte_kvargs_free(kvlist); +def: + adapter->loopback_en = loopback_en; + adapter->rx_func_sec = rx_io_func; + adapter->tx_func_sec = tx_io_func; + + return ret; +} + +static int rnp_post_handle(struct rnp_eth_adapter *adapter) +{ + bool on = false; + + if (!adapter->eth_dev) + return -ENOMEM; + if (adapter->do_fw_update && adapter->fw_path) { + rnp_fw_update(adapter); + adapter->do_fw_update = 0; + } + + if (adapter->fw_sfp_10g_1g_auto_det) + return rnp_hw_set_fw_10g_1g_auto_detch(adapter->eth_dev, 1); + + on = (adapter->fw_force_speed_1g == FOCE_SPEED_1G_ENABLED) ? 1 : 0; + if (adapter->fw_force_speed_1g != FOCE_SPEED_1G_NOT_SET) + return rnp_hw_set_fw_force_speed_1g(adapter->eth_dev, on); + + return 0; +} + static int rnp_eth_dev_init(struct rte_eth_dev *dev) { @@ -492,6 +648,11 @@ rnp_eth_dev_init(struct rte_eth_dev *dev) /* We need Use Device Id To Change The Resource Mode */ rnp_special_ops_init(dev); port->hw = hw; + ret = rnp_parse_devargs(adapter, pci_dev->device.devargs); + if (ret) { + PMD_DRV_LOG(ERR, "parse_devargs failed"); + return ret; + } for (p_id = 0; p_id < adapter->num_ports; p_id++) { /* port 0 resource has been alloced When Probe */ if (!p_id) { @@ -517,6 +678,9 @@ rnp_eth_dev_init(struct rte_eth_dev *dev) rnp_mac_rx_disable(eth_dev); rnp_mac_tx_disable(eth_dev); } + ret = rnp_post_handle(adapter); + if (ret) + goto eth_alloc_error; return 0; eth_alloc_error: diff --git a/drivers/net/rnp/rnp_mbx_fw.c b/drivers/net/rnp/rnp_mbx_fw.c index 23d366cbbe..d505c5732b 100644 --- a/drivers/net/rnp/rnp_mbx_fw.c +++ b/drivers/net/rnp/rnp_mbx_fw.c @@ -106,6 +106,27 @@ static int rnp_mbx_fw_post_req(struct rte_eth_dev *dev, return err; } +static int +rnp_mbx_write_posted_locked(struct rte_eth_dev *dev, struct mbx_fw_cmd_req *req) +{ + const struct rnp_mbx_api *ops = RNP_DEV_TO_MBX_OPS(dev); + struct rnp_hw *hw = RNP_DEV_TO_HW(dev); + int err = 0; + + rte_spinlock_lock(&hw->fw_lock); + + err = ops->write_posted(dev, (u32 *)req, + (req->datalen + MBX_REQ_HDR_LEN) / 4, MBX_FW); + if (err) { + RNP_PMD_LOG(ERR, "%s failed!\n", __func__); + goto quit; + } + +quit: + rte_spinlock_unlock(&hw->fw_lock); + return err; +} + static int rnp_fw_get_capablity(struct rte_eth_dev *dev, struct phy_abilities *abil) { @@ -382,3 +403,146 @@ int rnp_mbx_get_lane_stat(struct rte_eth_dev *dev) quit: return err; } + +static int rnp_maintain_req(struct rte_eth_dev *dev, + int cmd, + int arg0, + int req_data_bytes, + int reply_bytes, + phys_addr_t dma_phy_addr) +{ + struct rnp_hw *hw = RNP_DEV_TO_HW(dev); + struct mbx_req_cookie *cookie = NULL; + struct mbx_fw_cmd_req req; + int err; + + if (!hw->mbx.irq_enabled) + return -EIO; + cookie = rnp_memzone_reserve(hw->cookie_p_name, 0); + if (!cookie) + return -ENOMEM; + memset(&req, 0, sizeof(req)); + cookie->timeout_ms = 60 * 1000; /* 60s */ + + build_maintain_req(&req, + cookie, + cmd, + arg0, + req_data_bytes, + reply_bytes, + dma_phy_addr & 0xffffffff, + (dma_phy_addr >> 32) & 0xffffffff); + + err = rnp_mbx_fw_post_req(dev, &req, cookie); + + return (err) ? -EIO : 0; +} + +int rnp_fw_update(struct rnp_eth_adapter *adapter) +{ + const struct rte_memzone *rz = NULL; + struct maintain_req *mt; + FILE *file; + int fsz; +#define MAX_FW_BIN_SZ (552 * 1024) +#define FW_256KB (256 * 1024) + + RNP_PMD_LOG(INFO, "%s: %s\n", __func__, adapter->fw_path); + + file = fopen(adapter->fw_path, "rb"); + if (!file) { + RNP_PMD_LOG(ERR, + "RNP: [%s] %s can't open for read\n", + __func__, + adapter->fw_path); + return -ENOENT; + } + /* get dma */ + rz = rte_memzone_reserve("fw_update", MAX_FW_BIN_SZ, SOCKET_ID_ANY, 4); + if (rz == NULL) { + RNP_PMD_LOG(ERR, "RNP: [%s] not memory:%d\n", __func__, + MAX_FW_BIN_SZ); + return -EFBIG; + } + memset(rz->addr, 0xff, rz->len); + mt = (struct maintain_req *)rz->addr; + + /* read data */ + fsz = fread(mt->data, 1, rz->len, file); + if (fsz <= 0) { + RNP_PMD_LOG(INFO, "RNP: [%s] read failed! err:%d\n", + __func__, fsz); + return -EIO; + } + fclose(file); + + if (fsz > ((256 + 4) * 1024)) { + printf("fw length:%d is two big. not supported!\n", fsz); + return -EINVAL; + } + RNP_PMD_LOG(NOTICE, "RNP: fw update ...\n"); + fflush(stdout); + + /* ==== update fw */ + mt->magic = MAINTAIN_MAGIC; + mt->cmd = MT_WRITE_FLASH; + mt->arg0 = 1; + mt->req_data_bytes = (fsz > FW_256KB) ? FW_256KB : fsz; + mt->reply_bytes = 0; + + if (rnp_maintain_req(adapter->eth_dev, mt->cmd, mt->arg0, + mt->req_data_bytes, mt->reply_bytes, rz->iova)) + RNP_PMD_LOG(ERR, "maintain request failed!\n"); + else + RNP_PMD_LOG(INFO, "maintail request done!\n"); + + /* ==== update cfg */ + if (fsz > FW_256KB) { + mt->magic = MAINTAIN_MAGIC; + mt->cmd = MT_WRITE_FLASH; + mt->arg0 = 2; + mt->req_data_bytes = 4096; + mt->reply_bytes = 0; + memcpy(mt->data, mt->data + FW_256KB, mt->req_data_bytes); + + if (rnp_maintain_req(adapter->eth_dev, + mt->cmd, mt->arg0, mt->req_data_bytes, + mt->reply_bytes, rz->iova)) + RNP_PMD_LOG(ERR, "maintain request failed!\n"); + else + RNP_PMD_LOG(INFO, "maintail request done!\n"); + } + + RNP_PMD_LOG(NOTICE, "done\n"); + fflush(stdout); + + rte_memzone_free(rz); + + exit(0); + + return 0; +} + +static int rnp_mbx_set_dump(struct rte_eth_dev *dev, int flag) +{ + struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev); + struct mbx_fw_cmd_req req; + int err; + + memset(&req, 0, sizeof(req)); + build_set_dump(&req, port->attr.nr_lane, flag); + + err = rnp_mbx_write_posted_locked(dev, &req); + + return err; +} + +int rnp_hw_set_fw_10g_1g_auto_detch(struct rte_eth_dev *dev, int enable) +{ + return rnp_mbx_set_dump(dev, 0x01140000 | (enable & 1)); +} + +int rnp_hw_set_fw_force_speed_1g(struct rte_eth_dev *dev, int enable) +{ + return rnp_mbx_set_dump(dev, 0x01150000 | (enable & 1)); +} diff --git a/drivers/net/rnp/rnp_mbx_fw.h b/drivers/net/rnp/rnp_mbx_fw.h index 7bf5c2a865..051ffd1bdc 100644 --- a/drivers/net/rnp/rnp_mbx_fw.h +++ b/drivers/net/rnp/rnp_mbx_fw.h @@ -16,6 +16,17 @@ struct mbx_req_cookie { int priv_len; char priv[RNP_MAX_SHARE_MEM]; }; +struct maintain_req { + int magic; +#define MAINTAIN_MAGIC 0xa6a7a8a9 + + int cmd; + int arg0; + int req_data_bytes; + int reply_bytes; + char data[0]; +} __rte_packed; + enum GENERIC_CMD { /* link configuration admin commands */ GET_PHY_ABALITY = 0x0601, @@ -23,6 +34,9 @@ enum GENERIC_CMD { RESET_PHY = 0x0603, GET_LANE_STATUS = 0x0610, SET_EVENT_MASK = 0x0613, + /* fw update */ + FW_MAINTAIN = 0x0701, + SET_DUMP = 0x0a10, }; enum link_event_mask { @@ -211,6 +225,21 @@ struct mbx_fw_cmd_req { struct { int nr_lane; } get_lane_st; + + struct { + int cmd; +#define MT_WRITE_FLASH 1 + int arg0; + int req_bytes; + int reply_bytes; + int ddr_lo; + int ddr_hi; + } maintain; + + struct { + int flag; + int nr_lane; + } set_dump; }; } __rte_packed __rte_aligned(4); @@ -284,6 +313,43 @@ build_get_lane_status_req(struct mbx_fw_cmd_req *req, req->get_lane_st.nr_lane = nr_lane; } +static inline void +build_maintain_req(struct mbx_fw_cmd_req *req, + void *cookie, + int cmd, + int arg0, + int req_bytes, + int reply_bytes, + u32 dma_phy_lo, + u32 dma_phy_hi) +{ + req->flags = 0; + req->opcode = FW_MAINTAIN; + req->datalen = sizeof(req->maintain); + req->cookie = cookie; + req->reply_lo = 0; + req->reply_hi = 0; + req->maintain.cmd = cmd; + req->maintain.arg0 = arg0; + req->maintain.req_bytes = req_bytes; + req->maintain.reply_bytes = reply_bytes; + req->maintain.ddr_lo = dma_phy_lo; + req->maintain.ddr_hi = dma_phy_hi; +} + +static inline void +build_set_dump(struct mbx_fw_cmd_req *req, int nr_lane, int flag) +{ + req->flags = 0; + req->opcode = SET_DUMP; + req->datalen = sizeof(req->set_dump); + req->cookie = NULL; + req->reply_lo = 0; + req->reply_hi = 0; + req->set_dump.flag = flag; + req->set_dump.nr_lane = nr_lane; +} + int rnp_mbx_get_capability(struct rte_eth_dev *dev, int *lane_mask, int *nic_mode); @@ -295,4 +361,7 @@ rnp_fw_get_macaddr(struct rte_eth_dev *dev, u8 *mac_addr, int nr_lane); int rnp_mbx_get_lane_stat(struct rte_eth_dev *dev); +int rnp_fw_update(struct rnp_eth_adapter *adapter); +int rnp_hw_set_fw_10g_1g_auto_detch(struct rte_eth_dev *dev, int enable); +int rnp_hw_set_fw_force_speed_1g(struct rte_eth_dev *dev, int enable); #endif /* __RNP_MBX_FW_H__*/