From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id AF644461C1; Sat, 8 Feb 2025 03:45:52 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 7CE2740677; Sat, 8 Feb 2025 03:44:56 +0100 (CET) Received: from localhost.localdomain (unknown [103.233.162.252]) by mails.dpdk.org (Postfix) with ESMTP id B13B840663 for ; Sat, 8 Feb 2025 03:44:50 +0100 (CET) Received: by localhost.localdomain (Postfix, from userid 0) id D8E73A3245; Sat, 8 Feb 2025 10:44:20 +0800 (CST) From: Wenbo Cao To: thomas@monjalon.net, Wenbo Cao Cc: stephen@networkplumber.org, dev@dpdk.org, ferruh.yigit@amd.com, andrew.rybchenko@oktetlabs.ru, yaojun@mucse.com Subject: [PATCH v7 13/28] net/rnp: add support link setup operations Date: Sat, 8 Feb 2025 10:43:50 +0800 Message-Id: <1738982645-34550-14-git-send-email-caowenbo@mucse.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1738982645-34550-1-git-send-email-caowenbo@mucse.com> References: <1738982645-34550-1-git-send-email-caowenbo@mucse.com> 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 set link_down/link_up implent Signed-off-by: Wenbo Cao --- drivers/net/rnp/base/rnp_eth_regs.h | 3 ++ drivers/net/rnp/base/rnp_fw_cmd.c | 22 +++++++++ drivers/net/rnp/base/rnp_fw_cmd.h | 6 +++ drivers/net/rnp/base/rnp_mbx_fw.c | 33 +++++++++++++ drivers/net/rnp/base/rnp_mbx_fw.h | 1 + drivers/net/rnp/rnp_ethdev.c | 4 ++ drivers/net/rnp/rnp_link.c | 99 +++++++++++++++++++++++++++++++++++++ drivers/net/rnp/rnp_link.h | 2 + 8 files changed, 170 insertions(+) diff --git a/drivers/net/rnp/base/rnp_eth_regs.h b/drivers/net/rnp/base/rnp_eth_regs.h index be7ed5b..c74886e 100644 --- a/drivers/net/rnp/base/rnp_eth_regs.h +++ b/drivers/net/rnp/base/rnp_eth_regs.h @@ -5,6 +5,9 @@ #ifndef _RNP_ETH_REGS_H #define _RNP_ETH_REGS_H +#define RNP_ETH_TX_FIFO_STATE _ETH_(0x0330) +#define RNP_ETH_TX_FIFO_EMPT(lane) ((1 << (lane)) | (1 << ((lane) + 4))) + #define RNP_E_ENG_BYPASS _ETH_(0x8000) #define RNP_E_VXLAN_PARSE_EN _ETH_(0x8004) #define RNP_E_FILTER_EN _ETH_(0x801c) diff --git a/drivers/net/rnp/base/rnp_fw_cmd.c b/drivers/net/rnp/base/rnp_fw_cmd.c index c5ae7b9..17d3bb2 100644 --- a/drivers/net/rnp/base/rnp_fw_cmd.c +++ b/drivers/net/rnp/base/rnp_fw_cmd.c @@ -107,6 +107,25 @@ arg->event_en = req_arg->param2; } +static void +rnp_build_ifup_down(struct rnp_mbx_fw_cmd_req *req, + struct rnp_fw_req_arg *req_arg, + void *cookie) +{ + struct rnp_ifup_down_req *arg = + (struct rnp_ifup_down_req *)req->data; + + req->flags = 0; + req->opcode = RNP_IFUP_DOWN; + req->datalen = sizeof(*arg); + req->cookie = cookie; + req->reply_lo = 0; + req->reply_hi = 0; + + arg->nr_lane = req_arg->param0; + arg->up = req_arg->param1; +} + int rnp_build_fwcmd_req(struct rnp_mbx_fw_cmd_req *req, struct rnp_fw_req_arg *arg, void *cookie) @@ -132,6 +151,9 @@ int rnp_build_fwcmd_req(struct rnp_mbx_fw_cmd_req *req, case RNP_SET_LANE_EVENT_EN: rnp_build_lane_evet_mask(req, arg, cookie); break; + case RNP_IFUP_DOWN: + rnp_build_ifup_down(req, arg, cookie); + break; default: err = -EOPNOTSUPP; } diff --git a/drivers/net/rnp/base/rnp_fw_cmd.h b/drivers/net/rnp/base/rnp_fw_cmd.h index c86a32a..6b34396 100644 --- a/drivers/net/rnp/base/rnp_fw_cmd.h +++ b/drivers/net/rnp/base/rnp_fw_cmd.h @@ -310,6 +310,12 @@ struct rnp_link_stat_req { struct rnp_port_stat states[RNP_MAX_PORT_OF_PF]; }; +struct rnp_ifup_down_req { + u32 nr_lane; + u32 up; + u8 rsvd[24]; +}; + struct rnp_mbx_fw_cmd_req { u16 flags; u16 opcode; diff --git a/drivers/net/rnp/base/rnp_mbx_fw.c b/drivers/net/rnp/base/rnp_mbx_fw.c index d15a639..8758437 100644 --- a/drivers/net/rnp/base/rnp_mbx_fw.c +++ b/drivers/net/rnp/base/rnp_mbx_fw.c @@ -464,3 +464,36 @@ int rnp_mbx_fw_reset_phy(struct rnp_hw *hw) return 0; } + +static void rnp_link_stat_reset(struct rnp_hw *hw, u16 lane) +{ + u32 state; + + spin_lock(&hw->link_sync); + state = RNP_E_REG_RD(hw, RNP_FW_LINK_SYNC); + state &= ~RNP_LINK_MAGIC_MASK; + state |= RNP_LINK_MAGIC_CODE; + state &= ~RTE_BIT32(lane); + + RNP_E_REG_WR(hw, RNP_FW_LINK_SYNC, state); + rte_spinlock_unlock(&hw->link_sync); +} + +int rnp_mbx_fw_ifup_down(struct rnp_eth_port *port, bool up) +{ + u16 nr_lane = port->attr.nr_lane; + struct rnp_hw *hw = port->hw; + struct rnp_fw_req_arg arg; + int err; + + memset(&arg, 0, sizeof(arg)); + arg.opcode = RNP_IFUP_DOWN; + arg.param0 = nr_lane; + arg.param1 = up; + + err = rnp_fw_send_norep_cmd(port, &arg); + /* force firmware send irq event to dpdk */ + if (!err && up) + rnp_link_stat_reset(hw, nr_lane); + return err; +} diff --git a/drivers/net/rnp/base/rnp_mbx_fw.h b/drivers/net/rnp/base/rnp_mbx_fw.h index 159a023..397d2ec 100644 --- a/drivers/net/rnp/base/rnp_mbx_fw.h +++ b/drivers/net/rnp/base/rnp_mbx_fw.h @@ -19,5 +19,6 @@ int rnp_rcv_msg_from_fw(struct rnp_eth_adapter *adapter, u32 *msgbuf); int rnp_fw_mbx_ifup_down(struct rnp_eth_port *port, int up); int rnp_mbx_fw_lane_link_event_en(struct rnp_eth_port *port, bool en); +int rnp_mbx_fw_ifup_down(struct rnp_eth_port *port, bool up); #endif /* _RNP_MBX_FW_H_ */ diff --git a/drivers/net/rnp/rnp_ethdev.c b/drivers/net/rnp/rnp_ethdev.c index a3b84db..e229b2e 100644 --- a/drivers/net/rnp/rnp_ethdev.c +++ b/drivers/net/rnp/rnp_ethdev.c @@ -326,6 +326,7 @@ static int rnp_dev_start(struct rte_eth_dev *eth_dev) rnp_mbx_fw_lane_link_event_en(port, lsc); if (!lsc) rnp_run_link_poll_task(port); + rnp_dev_set_link_up(eth_dev); /* enable eth rx flow */ RNP_RX_ETH_ENABLE(hw, lane); port->port_stopped = 0; @@ -411,6 +412,7 @@ static int rnp_dev_stop(struct rte_eth_dev *eth_dev) /* clear the recorded link status */ memset(&link, 0, sizeof(link)); rte_eth_linkstatus_set(eth_dev, &link); + rnp_dev_set_link_down(eth_dev); rnp_disable_all_tx_queue(eth_dev); rnp_disable_all_rx_queue(eth_dev); rnp_mac_tx_disable(eth_dev); @@ -638,6 +640,8 @@ static int rnp_allmulticast_disable(struct rte_eth_dev *eth_dev) .rss_hash_conf_get = rnp_dev_rss_hash_conf_get, /* link impl */ .link_update = rnp_dev_link_update, + .dev_set_link_up = rnp_dev_set_link_up, + .dev_set_link_down = rnp_dev_set_link_down, }; static void diff --git a/drivers/net/rnp/rnp_link.c b/drivers/net/rnp/rnp_link.c index 2f94397..45f5c2d 100644 --- a/drivers/net/rnp/rnp_link.c +++ b/drivers/net/rnp/rnp_link.c @@ -338,3 +338,102 @@ static void rnp_dev_link_task(void *param) { rte_eal_alarm_cancel(rnp_dev_link_task, port->eth_dev); } + +int rnp_dev_set_link_up(struct rte_eth_dev *eth_dev) +{ + struct rnp_eth_port *port = RNP_DEV_TO_PORT(eth_dev); + uint16_t nr_lane = port->attr.nr_lane; + struct rnp_hw *hw = port->hw; + struct rnp_rx_queue *rxq; + uint16_t timeout; + uint16_t index; + uint32_t state; + uint16_t idx; + int ret = 0; + + PMD_INIT_FUNC_TRACE(); + + if (port->attr.link_ready) + return 0; + /* Cur link-state Is Down Verity The Rx Dma Queue State Is Empty */ + if (!port->attr.link_ready) { + for (idx = 0; idx < eth_dev->data->nb_rx_queues; idx++) { + rxq = eth_dev->data->rx_queues[idx]; + if (!rxq) + continue; + index = rxq->attr.index; + timeout = 0; + do { + if (!RNP_E_REG_RD(hw, RNP_RXQ_READY(index))) + break; + rte_delay_us(10); + timeout++; + } while (timeout < 1000); + } + } + ret = rnp_mbx_fw_ifup_down(port, TRUE); + if (ret) { + RNP_PMD_WARN("port[%d] is set linkup failed\n", + eth_dev->data->port_id); + return ret; + } + timeout = 0; + do { + rte_io_rmb(); + state = RNP_E_REG_RD(hw, RNP_FW_LINK_SYNC); + if (state & RTE_BIT32(nr_lane)) + break; + timeout++; + rte_delay_us(10); + } while (timeout < 100); + + return ret; +} + +int rnp_dev_set_link_down(struct rte_eth_dev *eth_dev) +{ + struct rnp_eth_port *port = RNP_DEV_TO_PORT(eth_dev); + uint16_t nr_lane = port->attr.nr_lane; + struct rnp_hw *hw = port->hw; + struct rnp_tx_queue *txq; + uint32_t timeout = 0; + uint32_t check_v; + uint32_t state; + uint16_t idx; + + PMD_INIT_FUNC_TRACE(); + RNP_RX_ETH_DISABLE(hw, nr_lane); + for (idx = 0; idx < eth_dev->data->nb_tx_queues; idx++) { + txq = eth_dev->data->tx_queues[idx]; + if (!txq) + continue; + txq->tx_link = false; + } + /* 2 Check eth tx fifo empty state */ + do { + state = RNP_E_REG_RD(hw, RNP_ETH_TX_FIFO_STATE); + check_v = RNP_ETH_TX_FIFO_EMPT(nr_lane); + state &= check_v; + if (state == check_v) + break; + rte_delay_us(10); + timeout++; + if (timeout >= 1000) { + RNP_PMD_WARN("lane[%d] isn't empty of link-down action", + nr_lane); + break; + } + } while (1); + /* 3 Tell Firmware Do Link-down Event Work */ + rnp_mbx_fw_ifup_down(port, FALSE); + /* 4 Wait For Link-Down that Firmware Do done */ + timeout = 0; + do { + if (!port->attr.link_ready) + break; + rte_delay_us(10); + timeout++; + } while (timeout < 2000); + + return 0; +} diff --git a/drivers/net/rnp/rnp_link.h b/drivers/net/rnp/rnp_link.h index f0705f1..d7e4a9b 100644 --- a/drivers/net/rnp/rnp_link.h +++ b/drivers/net/rnp/rnp_link.h @@ -32,5 +32,7 @@ int rnp_dev_link_update(struct rte_eth_dev *eth_dev, int wait_to_complete); void rnp_run_link_poll_task(struct rnp_eth_port *port); void rnp_cancel_link_poll_task(struct rnp_eth_port *port); +int rnp_dev_set_link_up(struct rte_eth_dev *eth_dev); +int rnp_dev_set_link_down(struct rte_eth_dev *eth_dev); #endif /* _RNP_LINK_H_ */ -- 1.8.3.1