From patchwork Mon Jan 2 15:32:15 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 13086782 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DA16BC3DA7A for ; Mon, 2 Jan 2023 15:32:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236244AbjABPcg (ORCPT ); Mon, 2 Jan 2023 10:32:36 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38342 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232479AbjABPcf (ORCPT ); Mon, 2 Jan 2023 10:32:35 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 26376CEE for ; Mon, 2 Jan 2023 07:32:35 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id D629EB80D3E for ; Mon, 2 Jan 2023 15:32:33 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 44A69C433EF; Mon, 2 Jan 2023 15:32:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672673552; bh=Qtcw4YiYQC6vFVBPGLZh6FrLkSqwMP0taIG1GVnfjtE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=VBBi3sWBE/Mn/iau/k+xzY8WqvJCC5FbnO9wGUjxRUj+p81ODJX58SzIgMe6gDX3D pUn7t8cR1lszXlzDp3SVr1/hvv2lc5bxe8SZcJL/XoY7QBgPdyVQqjqXrFcA4980EP SSxIJ1un2UJKAe4CwTNzeIHAzlDOy4nCUR5gOfy7b6mmbs0AjTxe8O61/vBYI6YDTn RV310MLRE89WyCIizi/CBsCerOx1C1Uw46mMye6PLzQMP6HdG5pwMaMtaQx2s3GwIi jAae50RTO0QFbmxqM0zVyT1HakJQCkcXPG5uLwdvkZ6X+gVURHkSkts0HnKATUJZWx OLHOUtbF71Nxw== From: Lorenzo Bianconi To: netdev@vger.kernel.org Cc: davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, lorenzo.bianconi@redhat.com, nbd@nbd.name, john@phrozen.org, sean.wang@mediatek.com, Mark-MC.Lee@mediatek.com, sujuan.chen@mediatek.com, daniel@makrotopia.org Subject: [PATCH net-next 1/5] net: ethernet: mtk_eth_soc: introduce mtk_hw_reset utility routine Date: Mon, 2 Jan 2023 16:32:15 +0100 Message-Id: <95bfdfb7061fe8ce4775a6367c9c3d63696a7b1c.1672672965.git.lorenzo@kernel.org> X-Mailer: git-send-email 2.39.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org This is a preliminary patch to add Wireless Ethernet Dispatcher reset support. Tested-by: Daniel Golle Co-developed-by: Sujuan Chen Signed-off-by: Sujuan Chen Signed-off-by: Lorenzo Bianconi --- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 36 +++++++++++++-------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c index e3de9a53b2d9..ce429deea389 100644 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c @@ -3471,6 +3471,27 @@ static void mtk_set_mcr_max_rx(struct mtk_mac *mac, u32 val) mtk_w32(mac->hw, mcr_new, MTK_MAC_MCR(mac->id)); } +static void mtk_hw_reset(struct mtk_eth *eth) +{ + u32 val; + + if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { + regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0); + val = RSTCTRL_PPE0_V2; + } else { + val = RSTCTRL_PPE0; + } + + if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) + val |= RSTCTRL_PPE1; + + ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val); + + if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) + regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, + 0x3ffffff); +} + static int mtk_hw_init(struct mtk_eth *eth) { u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA | @@ -3510,22 +3531,9 @@ static int mtk_hw_init(struct mtk_eth *eth) return 0; } - if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { - regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0); - val = RSTCTRL_PPE0_V2; - } else { - val = RSTCTRL_PPE0; - } - - if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) - val |= RSTCTRL_PPE1; - - ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val); + mtk_hw_reset(eth); if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { - regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, - 0x3ffffff); - /* Set FE to PDMAv2 if necessary */ val = mtk_r32(eth, MTK_FE_GLO_MISC); mtk_w32(eth, val | BIT(4), MTK_FE_GLO_MISC); From patchwork Mon Jan 2 15:32:16 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 13086783 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 688A0C3DA7A for ; Mon, 2 Jan 2023 15:32:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236400AbjABPcm (ORCPT ); Mon, 2 Jan 2023 10:32:42 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38370 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232479AbjABPci (ORCPT ); Mon, 2 Jan 2023 10:32:38 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6ED382BC8 for ; Mon, 2 Jan 2023 07:32:37 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 0AA1560C2A for ; Mon, 2 Jan 2023 15:32:37 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1608AC433D2; Mon, 2 Jan 2023 15:32:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672673556; bh=bw1ec3pKGpb+GBBanQlISCF/qA9bXpn0M+IOi41r4ao=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NFI0yipGCvF2PXeNSTeBYkp0+5KVVj8FyTGAJNRgLyUtaJovIMacusnL1oy3uZ2Q3 F8rU8SsZ9j3x1ZVPmVNFTlzkj7Ch5XadWIIAd+EF0BdKcCrXuoAFPTZIihVANLRuSz cN+iu8Q7fccZmj95ahcnUDhF6r0pBT0HoElirGyvSM/HnJwbtKF69u0U5KdAPVsec+ CPGgXWoBVdarGDJZlw/6o/cxMVVWVJ4KrtKi60qMNX0ZC4sUQjnSbnOGZUt8a7uC50 JSS9Sf6cGvnqIjH/cUhlgn/Ph/SYf2NalLhRPMwoS08/Gkf3YSyxcbeijzYmeX1Tb/ JZKnWz52MgiVA== From: Lorenzo Bianconi To: netdev@vger.kernel.org Cc: davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, lorenzo.bianconi@redhat.com, nbd@nbd.name, john@phrozen.org, sean.wang@mediatek.com, Mark-MC.Lee@mediatek.com, sujuan.chen@mediatek.com, daniel@makrotopia.org Subject: [PATCH net-next 2/5] net: ethernet: mtk_eth_soc: introduce mtk_hw_warm_reset support Date: Mon, 2 Jan 2023 16:32:16 +0100 Message-Id: <76198ccc715cc6f4fcf2fd62c7d66b71c247be86.1672672965.git.lorenzo@kernel.org> X-Mailer: git-send-email 2.39.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Introduce mtk_hw_warm_reset utility routine. This is a preliminary patch to align reset procedure to vendor sdk and avoid to power down the chip during hw reset. Tested-by: Daniel Golle Co-developed-by: Sujuan Chen Signed-off-by: Sujuan Chen Signed-off-by: Lorenzo Bianconi --- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 59 +++++++++++++++++++-- 1 file changed, 55 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c index ce429deea389..ffd4dbee0488 100644 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c @@ -3492,7 +3492,54 @@ static void mtk_hw_reset(struct mtk_eth *eth) 0x3ffffff); } -static int mtk_hw_init(struct mtk_eth *eth) +static u32 mtk_hw_reset_read(struct mtk_eth *eth) +{ + u32 val; + + regmap_read(eth->ethsys, ETHSYS_RSTCTRL, &val); + return val; +} + +static void mtk_hw_warm_reset(struct mtk_eth *eth) +{ + u32 rst_mask, val; + + regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, RSTCTRL_FE, + RSTCTRL_FE); + if (readx_poll_timeout_atomic(mtk_hw_reset_read, eth, val, + val & RSTCTRL_FE, 1, 1000)) { + dev_err(eth->dev, "warm reset failed\n"); + mtk_hw_reset(eth); + return; + } + + if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) + rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0_V2; + else + rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0; + + if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) + rst_mask |= RSTCTRL_PPE1; + + regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, rst_mask, rst_mask); + + udelay(1); + val = mtk_hw_reset_read(eth); + if (!(val & rst_mask)) + dev_err(eth->dev, "warm reset stage0 failed %08x (%08x)\n", + val, rst_mask); + + rst_mask |= RSTCTRL_FE; + regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, rst_mask, ~rst_mask); + + udelay(1); + val = mtk_hw_reset_read(eth); + if (val & rst_mask) + dev_err(eth->dev, "warm reset stage1 failed %08x (%08x)\n", + val, rst_mask); +} + +static int mtk_hw_init(struct mtk_eth *eth, bool reset) { u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA | ETHSYS_DMA_AG_MAP_PPE; @@ -3531,7 +3578,11 @@ static int mtk_hw_init(struct mtk_eth *eth) return 0; } - mtk_hw_reset(eth); + mdelay(100); + if (reset) + mtk_hw_warm_reset(eth); + else + mtk_hw_reset(eth); if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { /* Set FE to PDMAv2 if necessary */ @@ -3743,7 +3794,7 @@ static void mtk_pending_work(struct work_struct *work) if (eth->dev->pins) pinctrl_select_state(eth->dev->pins->p, eth->dev->pins->default_state); - mtk_hw_init(eth); + mtk_hw_init(eth, true); /* restart DMA and enable IRQs */ for (i = 0; i < MTK_MAC_COUNT; i++) { @@ -4372,7 +4423,7 @@ static int mtk_probe(struct platform_device *pdev) eth->msg_enable = netif_msg_init(mtk_msg_level, MTK_DEFAULT_MSG_ENABLE); INIT_WORK(ð->pending_work, mtk_pending_work); - err = mtk_hw_init(eth); + err = mtk_hw_init(eth, false); if (err) goto err_wed_exit; From patchwork Mon Jan 2 15:32:17 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 13086784 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CA89BC4708E for ; Mon, 2 Jan 2023 15:32:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236155AbjABPc4 (ORCPT ); Mon, 2 Jan 2023 10:32:56 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38466 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236404AbjABPco (ORCPT ); Mon, 2 Jan 2023 10:32:44 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 072D1A1A2 for ; Mon, 2 Jan 2023 07:32:43 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id A640FB80D85 for ; Mon, 2 Jan 2023 15:32:41 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 069E7C433D2; Mon, 2 Jan 2023 15:32:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672673560; bh=/sRFg6SqmVPO/qpLKPE3qyTl/CBHUjVYNZNwPNnVhZk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Y5XxGIJ7tMzzS7rtnA8nXQcAq/zM7Fm+Njc9F5IUPyXlKelDd8PJAteAAgspsj9H3 LJlH1RAhpRd6pcVqcB8gxYhn0mr7sN35Yvn3BBV10+iWkSju3Bq7F+KAvEhYkqaaXP QmZBh6M8/wIe5NcY2xTtby0ylRvgz0y6/eteulmP5ulvJvKRzKPcJ3E7FIrmQ11jhy b+mkwq2eMdtl7E/n5s0lpC0DltyOV3QP6xl/C82gxPpb2HEvB3eQTJqVkIUArOE1gH 2L2dLAOuGVi7xHqY4dBLWpuwgVtNTzL0438qTTVZxgBZ9227PfWNKFohPOuDZcB55f 2LtWiK35l/y7Q== From: Lorenzo Bianconi To: netdev@vger.kernel.org Cc: davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, lorenzo.bianconi@redhat.com, nbd@nbd.name, john@phrozen.org, sean.wang@mediatek.com, Mark-MC.Lee@mediatek.com, sujuan.chen@mediatek.com, daniel@makrotopia.org Subject: [PATCH net-next 3/5] net: ethernet: mtk_eth_soc: align reset procedure to vendor sdk Date: Mon, 2 Jan 2023 16:32:17 +0100 Message-Id: X-Mailer: git-send-email 2.39.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Avoid to power-down the ethernet chip during hw reset and align reset procedure to vendor sdk. Tested-by: Daniel Golle Co-developed-by: Sujuan Chen Signed-off-by: Sujuan Chen Signed-off-by: Lorenzo Bianconi --- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 86 ++++++++++++++------ drivers/net/ethernet/mediatek/mtk_eth_soc.h | 12 +++ drivers/net/ethernet/mediatek/mtk_ppe.c | 27 ++++++ drivers/net/ethernet/mediatek/mtk_ppe.h | 1 + drivers/net/ethernet/mediatek/mtk_ppe_regs.h | 6 ++ 5 files changed, 108 insertions(+), 24 deletions(-) diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c index ffd4dbee0488..ba924ceb6c94 100644 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c @@ -2984,14 +2984,29 @@ static void mtk_dma_free(struct mtk_eth *eth) kfree(eth->scratch_head); } +static bool mtk_hw_reset_check(struct mtk_eth *eth) +{ + u32 val = mtk_r32(eth, MTK_INT_STATUS2); + + return (val & MTK_FE_INT_FQ_EMPTY) || (val & MTK_FE_INT_RFIFO_UF) || + (val & MTK_FE_INT_RFIFO_OV) || (val & MTK_FE_INT_TSO_FAIL) || + (val & MTK_FE_INT_TSO_ALIGN) || (val & MTK_FE_INT_TSO_ILLEGAL); +} + static void mtk_tx_timeout(struct net_device *dev, unsigned int txqueue) { struct mtk_mac *mac = netdev_priv(dev); struct mtk_eth *eth = mac->hw; + if (!mtk_hw_reset_check(eth)) + return; + eth->netdev[mac->id]->stats.tx_errors++; - netif_err(eth, tx_err, dev, - "transmit timed out\n"); + netif_err(eth, tx_err, dev, "transmit timed out\n"); + + if (test_bit(MTK_RESETTING, ð->state)) + return; + schedule_work(ð->pending_work); } @@ -3546,15 +3561,17 @@ static int mtk_hw_init(struct mtk_eth *eth, bool reset) const struct mtk_reg_map *reg_map = eth->soc->reg_map; int i, val, ret; - if (test_and_set_bit(MTK_HW_INIT, ð->state)) + if (!reset && test_and_set_bit(MTK_HW_INIT, ð->state)) return 0; - pm_runtime_enable(eth->dev); - pm_runtime_get_sync(eth->dev); + if (!reset) { + pm_runtime_enable(eth->dev); + pm_runtime_get_sync(eth->dev); - ret = mtk_clk_enable(eth); - if (ret) - goto err_disable_pm; + ret = mtk_clk_enable(eth); + if (ret) + goto err_disable_pm; + } if (eth->ethsys) regmap_update_bits(eth->ethsys, ETHSYS_DMA_AG_MAP, dma_mask, @@ -3686,8 +3703,10 @@ static int mtk_hw_init(struct mtk_eth *eth, bool reset) return 0; err_disable_pm: - pm_runtime_put_sync(eth->dev); - pm_runtime_disable(eth->dev); + if (!reset) { + pm_runtime_put_sync(eth->dev); + pm_runtime_disable(eth->dev); + } return ret; } @@ -3769,46 +3788,65 @@ static int mtk_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) static void mtk_pending_work(struct work_struct *work) { struct mtk_eth *eth = container_of(work, struct mtk_eth, pending_work); - int err, i; unsigned long restart = 0; + u32 val; + int i; rtnl_lock(); - - dev_dbg(eth->dev, "[%s][%d] reset\n", __func__, __LINE__); set_bit(MTK_RESETTING, ð->state); + /* disabe FE P3 and P4 */ + val = mtk_r32(eth, MTK_FE_GLO_CFG) | MTK_FE_LINK_DOWN_P3; + if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) + val |= MTK_FE_LINK_DOWN_P4; + mtk_w32(eth, val, MTK_FE_GLO_CFG); + + /* adjust PPE configurations to prepare for reset */ + for (i = 0; i < ARRAY_SIZE(eth->ppe); i++) + mtk_ppe_prepare_reset(eth->ppe[i]); + + /* disable NETSYS interrupts */ + mtk_w32(eth, 0, MTK_FE_INT_ENABLE); + + /* force link down GMAC */ + for (i = 0; i < 2; i++) { + val = mtk_r32(eth, MTK_MAC_MCR(i)) & ~MAC_MCR_FORCE_LINK; + mtk_w32(eth, val, MTK_MAC_MCR(i)); + } + /* stop all devices to make sure that dma is properly shut down */ for (i = 0; i < MTK_MAC_COUNT; i++) { - if (!eth->netdev[i]) + if (!eth->netdev[i] || !netif_running(eth->netdev[i])) continue; + mtk_stop(eth->netdev[i]); __set_bit(i, &restart); } - dev_dbg(eth->dev, "[%s][%d] mtk_stop ends\n", __func__, __LINE__); - - /* restart underlying hardware such as power, clock, pin mux - * and the connected phy - */ - mtk_hw_deinit(eth); + mdelay(15); if (eth->dev->pins) pinctrl_select_state(eth->dev->pins->p, eth->dev->pins->default_state); + mtk_hw_init(eth, true); /* restart DMA and enable IRQs */ for (i = 0; i < MTK_MAC_COUNT; i++) { if (!test_bit(i, &restart)) continue; - err = mtk_open(eth->netdev[i]); - if (err) { + + if (mtk_open(eth->netdev[i])) { netif_alert(eth, ifup, eth->netdev[i], - "Driver up/down cycle failed, closing device.\n"); + "Driver up/down cycle failed\n"); dev_close(eth->netdev[i]); } } - dev_dbg(eth->dev, "[%s][%d] reset done\n", __func__, __LINE__); + /* enabe FE P3 and P4 */ + val = mtk_r32(eth, MTK_FE_GLO_CFG) & ~MTK_FE_LINK_DOWN_P3; + if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) + val &= ~MTK_FE_LINK_DOWN_P4; + mtk_w32(eth, val, MTK_FE_GLO_CFG); clear_bit(MTK_RESETTING, ð->state); diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h index 18a50529ce7b..a8066b3ee3ed 100644 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h @@ -77,12 +77,24 @@ #define MTK_HW_LRO_REPLACE_DELTA 1000 #define MTK_HW_LRO_SDL_REMAIN_ROOM 1522 +/* Frame Engine Global Configuration */ +#define MTK_FE_GLO_CFG 0x00 +#define MTK_FE_LINK_DOWN_P3 BIT(11) +#define MTK_FE_LINK_DOWN_P4 BIT(12) + /* Frame Engine Global Reset Register */ #define MTK_RST_GL 0x04 #define RST_GL_PSE BIT(0) /* Frame Engine Interrupt Status Register */ #define MTK_INT_STATUS2 0x08 +#define MTK_FE_INT_ENABLE 0x0c +#define MTK_FE_INT_FQ_EMPTY BIT(8) +#define MTK_FE_INT_TSO_FAIL BIT(12) +#define MTK_FE_INT_TSO_ILLEGAL BIT(13) +#define MTK_FE_INT_TSO_ALIGN BIT(14) +#define MTK_FE_INT_RFIFO_OV BIT(18) +#define MTK_FE_INT_RFIFO_UF BIT(19) #define MTK_GDM1_AF BIT(28) #define MTK_GDM2_AF BIT(29) diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.c b/drivers/net/ethernet/mediatek/mtk_ppe.c index 269208a841c7..994408d8f416 100644 --- a/drivers/net/ethernet/mediatek/mtk_ppe.c +++ b/drivers/net/ethernet/mediatek/mtk_ppe.c @@ -730,6 +730,33 @@ int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) return __mtk_foe_entry_idle_time(ppe, entry->data.ib1); } +int mtk_ppe_prepare_reset(struct mtk_ppe *ppe) +{ + if (!ppe) + return -EINVAL; + + /* disable KA */ + ppe_clear(ppe, MTK_PPE_TB_CFG, MTK_PPE_TB_CFG_KEEPALIVE); + ppe_clear(ppe, MTK_PPE_BIND_LMT1, MTK_PPE_NTU_KEEPALIVE); + ppe_w32(ppe, MTK_PPE_KEEPALIVE, 0); + mdelay(10); + + /* set KA timer to maximum */ + ppe_set(ppe, MTK_PPE_BIND_LMT1, MTK_PPE_NTU_KEEPALIVE); + ppe_w32(ppe, MTK_PPE_KEEPALIVE, 0xffffffff); + + /* set KA tick select */ + ppe_set(ppe, MTK_PPE_TB_CFG, MTK_PPE_TB_TICK_SEL); + ppe_set(ppe, MTK_PPE_TB_CFG, MTK_PPE_TB_CFG_KEEPALIVE); + mdelay(10); + + /* disable scan mode */ + ppe_clear(ppe, MTK_PPE_TB_CFG, MTK_PPE_TB_CFG_SCAN_MODE); + mdelay(10); + + return mtk_ppe_wait_busy(ppe); +} + struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int version, int index) { diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.h b/drivers/net/ethernet/mediatek/mtk_ppe.h index ea64fac1d425..16b02e1d4649 100644 --- a/drivers/net/ethernet/mediatek/mtk_ppe.h +++ b/drivers/net/ethernet/mediatek/mtk_ppe.h @@ -309,6 +309,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, void mtk_ppe_deinit(struct mtk_eth *eth); void mtk_ppe_start(struct mtk_ppe *ppe); int mtk_ppe_stop(struct mtk_ppe *ppe); +int mtk_ppe_prepare_reset(struct mtk_ppe *ppe); void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash); diff --git a/drivers/net/ethernet/mediatek/mtk_ppe_regs.h b/drivers/net/ethernet/mediatek/mtk_ppe_regs.h index 59596d823d8b..0fdb983b0a88 100644 --- a/drivers/net/ethernet/mediatek/mtk_ppe_regs.h +++ b/drivers/net/ethernet/mediatek/mtk_ppe_regs.h @@ -58,6 +58,12 @@ #define MTK_PPE_TB_CFG_SCAN_MODE GENMASK(17, 16) #define MTK_PPE_TB_CFG_HASH_DEBUG GENMASK(19, 18) #define MTK_PPE_TB_CFG_INFO_SEL BIT(20) +#define MTK_PPE_TB_TICK_SEL BIT(24) + +#define MTK_PPE_BIND_LMT1 0x230 +#define MTK_PPE_NTU_KEEPALIVE GENMASK(23, 16) + +#define MTK_PPE_KEEPALIVE 0x234 enum { MTK_PPE_SCAN_MODE_DISABLED, From patchwork Mon Jan 2 15:32:18 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 13086785 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 96280C3DA7A for ; Mon, 2 Jan 2023 15:32:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236404AbjABPc6 (ORCPT ); Mon, 2 Jan 2023 10:32:58 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38452 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236407AbjABPcy (ORCPT ); Mon, 2 Jan 2023 10:32:54 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CB3509FF2 for ; Mon, 2 Jan 2023 07:32:46 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 7F79AB80D85 for ; Mon, 2 Jan 2023 15:32:45 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id E0510C433D2; Mon, 2 Jan 2023 15:32:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672673564; bh=gTRQqnkoUWGQ65tvhWsJIqWS860SI2FNauc8bhtMbdU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=EneK5Mt4E6yDd9cIgdOOXQe6yg59DpxVelgeQCy8RwfwFiQJLZOsERl83hZTOBian 4Tx2SF8EcWF54AwzvtfoQcfUcycFozY11mnkc0Ve4YiEKwcwVJsW1l9qfHhxE/cYbj +3GdtLzIFQlFq7kKvrOR2SrwqVVaYFKAnLatplNWPET6HJ438XQ2HGQgulXayFJqyC 7QstxwUipGOHScYR0MdSvVqmrizJGzjMwKhqEeLAfb/Z2xPmt4UMhqDF697J2PPRHk uFtDfI1/Grp4xtEt7NSxaD0JH40Vln0zc6THYBLj/RnyhngnrESzUWADMvbiEOs1wN 1XFxe0/6B+/kw== From: Lorenzo Bianconi To: netdev@vger.kernel.org Cc: davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, lorenzo.bianconi@redhat.com, nbd@nbd.name, john@phrozen.org, sean.wang@mediatek.com, Mark-MC.Lee@mediatek.com, sujuan.chen@mediatek.com, daniel@makrotopia.org Subject: [PATCH net-next 4/5] net: ethernet: mtk_eth_soc: add dma checks to mtk_hw_reset_check Date: Mon, 2 Jan 2023 16:32:18 +0100 Message-Id: <1d0996eef866c99ebafd34284f2edba995859356.1672672965.git.lorenzo@kernel.org> X-Mailer: git-send-email 2.39.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Introduce mtk_hw_check_dma_hang routine to monitor possible dma hangs. Tested-by: Daniel Golle Co-developed-by: Sujuan Chen Signed-off-by: Sujuan Chen Signed-off-by: Lorenzo Bianconi --- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 103 ++++++++++++++++++++ drivers/net/ethernet/mediatek/mtk_eth_soc.h | 26 +++++ 2 files changed, 129 insertions(+) diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c index ba924ceb6c94..bafae4f0312e 100644 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c @@ -51,6 +51,7 @@ static const struct mtk_reg_map mtk_reg_map = { .delay_irq = 0x0a0c, .irq_status = 0x0a20, .irq_mask = 0x0a28, + .adma_rx_dbg0 = 0x0a38, .int_grp = 0x0a50, }, .qdma = { @@ -82,6 +83,8 @@ static const struct mtk_reg_map mtk_reg_map = { [0] = 0x2800, [1] = 0x2c00, }, + .pse_iq_sta = 0x0110, + .pse_oq_sta = 0x0118, }; static const struct mtk_reg_map mt7628_reg_map = { @@ -112,6 +115,7 @@ static const struct mtk_reg_map mt7986_reg_map = { .delay_irq = 0x620c, .irq_status = 0x6220, .irq_mask = 0x6228, + .adma_rx_dbg0 = 0x6238, .int_grp = 0x6250, }, .qdma = { @@ -143,6 +147,8 @@ static const struct mtk_reg_map mt7986_reg_map = { [0] = 0x4800, [1] = 0x4c00, }, + .pse_iq_sta = 0x0180, + .pse_oq_sta = 0x01a0, }; /* strings used by ethtool */ @@ -3554,6 +3560,99 @@ static void mtk_hw_warm_reset(struct mtk_eth *eth) val, rst_mask); } +static bool mtk_hw_check_dma_hang(struct mtk_eth *eth) +{ + const struct mtk_reg_map *reg_map = eth->soc->reg_map; + bool gmac1_tx, gmac2_tx, gdm1_tx, gdm2_tx; + bool oq_hang, cdm1_busy, adma_busy; + bool wtx_busy, cdm_full, oq_free; + u32 wdidx, val, gdm1_fc, gdm2_fc; + bool qfsm_hang, qfwd_hang; + bool ret = false; + + if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) + return false; + + /* WDMA sanity checks */ + wdidx = mtk_r32(eth, reg_map->wdma_base[0] + 0xc); + + val = mtk_r32(eth, reg_map->wdma_base[0] + 0x204); + wtx_busy = FIELD_GET(MTK_TX_DMA_BUSY, val); + + val = mtk_r32(eth, reg_map->wdma_base[0] + 0x230); + cdm_full = !FIELD_GET(MTK_CDM_TXFIFO_RDY, val); + + oq_free = (!(mtk_r32(eth, reg_map->pse_oq_sta) & GENMASK(24, 16)) && + !(mtk_r32(eth, reg_map->pse_oq_sta + 0x4) & GENMASK(8, 0)) && + !(mtk_r32(eth, reg_map->pse_oq_sta + 0x10) & GENMASK(24, 16))); + + if (wdidx == eth->reset.wdidx && wtx_busy && cdm_full && oq_free) { + if (++eth->reset.wdma_hang_count > 2) { + eth->reset.wdma_hang_count = 0; + ret = true; + } + goto out; + } + + /* QDMA sanity checks */ + qfsm_hang = !!mtk_r32(eth, reg_map->qdma.qtx_cfg + 0x234); + qfwd_hang = !mtk_r32(eth, reg_map->qdma.qtx_cfg + 0x308); + + gdm1_tx = FIELD_GET(GENMASK(31, 16), mtk_r32(eth, MTK_FE_GDM1_FSM)) > 0; + gdm2_tx = FIELD_GET(GENMASK(31, 16), mtk_r32(eth, MTK_FE_GDM2_FSM)) > 0; + gmac1_tx = FIELD_GET(GENMASK(31, 24), mtk_r32(eth, MTK_MAC_FSM(0))) != 1; + gmac2_tx = FIELD_GET(GENMASK(31, 24), mtk_r32(eth, MTK_MAC_FSM(1))) != 1; + gdm1_fc = mtk_r32(eth, reg_map->gdm1_cnt + 0x24); + gdm2_fc = mtk_r32(eth, reg_map->gdm1_cnt + 0x64); + + if (qfsm_hang && qfwd_hang && + ((gdm1_tx && gmac1_tx && gdm1_fc < 1) || + (gdm2_tx && gmac2_tx && gdm2_fc < 1))) { + if (++eth->reset.qdma_hang_count > 2) { + eth->reset.qdma_hang_count = 0; + ret = true; + } + goto out; + } + + /* ADMA sanity checks */ + oq_hang = !!(mtk_r32(eth, reg_map->pse_oq_sta) & GENMASK(8, 0)); + cdm1_busy = !!(mtk_r32(eth, MTK_FE_CDM1_FSM) & GENMASK(31, 16)); + adma_busy = !(mtk_r32(eth, reg_map->pdma.adma_rx_dbg0) & GENMASK(4, 0)) && + !(mtk_r32(eth, reg_map->pdma.adma_rx_dbg0) & BIT(6)); + + if (oq_hang && cdm1_busy && adma_busy) { + if (++eth->reset.adma_hang_count > 2) { + eth->reset.adma_hang_count = 0; + ret = true; + } + goto out; + } + + eth->reset.wdma_hang_count = 0; + eth->reset.qdma_hang_count = 0; + eth->reset.adma_hang_count = 0; +out: + eth->reset.wdidx = wdidx; + + return ret; +} + +static void mtk_hw_reset_monitor_work(struct work_struct *work) +{ + struct delayed_work *del_work = to_delayed_work(work); + struct mtk_eth *eth = container_of(del_work, struct mtk_eth, + reset.monitor_work); + + /* DMA stuck checks */ + if (!test_bit(MTK_RESETTING, ð->state) && + mtk_hw_check_dma_hang(eth)) + schedule_work(ð->pending_work); + + schedule_delayed_work(ð->reset.monitor_work, + MTK_DMA_MONITOR_TIMEOUT); +} + static int mtk_hw_init(struct mtk_eth *eth, bool reset) { u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA | @@ -3894,6 +3993,7 @@ static int mtk_cleanup(struct mtk_eth *eth) mtk_unreg_dev(eth); mtk_free_dev(eth); cancel_work_sync(ð->pending_work); + cancel_delayed_work_sync(ð->reset.monitor_work); return 0; } @@ -4348,6 +4448,7 @@ static int mtk_probe(struct platform_device *pdev) eth->rx_dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE; INIT_WORK(ð->rx_dim.work, mtk_dim_rx); + INIT_DELAYED_WORK(ð->reset.monitor_work, mtk_hw_reset_monitor_work); eth->tx_dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE; INIT_WORK(ð->tx_dim.work, mtk_dim_tx); @@ -4550,6 +4651,8 @@ static int mtk_probe(struct platform_device *pdev) netif_napi_add(ð->dummy_dev, ð->rx_napi, mtk_napi_rx); platform_set_drvdata(pdev, eth); + schedule_delayed_work(ð->reset.monitor_work, + MTK_DMA_MONITOR_TIMEOUT); return 0; diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h index a8066b3ee3ed..dff0e3ad2de6 100644 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h @@ -284,6 +284,8 @@ #define MTK_RX_DONE_INT_V2 BIT(14) +#define MTK_CDM_TXFIFO_RDY BIT(7) + /* QDMA Interrupt grouping registers */ #define MTK_RLS_DONE_INT BIT(0) @@ -574,6 +576,17 @@ #define MT7628_SDM_RBCNT (MT7628_SDM_OFFSET + 0x10c) #define MT7628_SDM_CS_ERR (MT7628_SDM_OFFSET + 0x110) +#define MTK_FE_CDM1_FSM 0x220 +#define MTK_FE_CDM2_FSM 0x224 +#define MTK_FE_CDM3_FSM 0x238 +#define MTK_FE_CDM4_FSM 0x298 +#define MTK_FE_CDM5_FSM 0x318 +#define MTK_FE_CDM6_FSM 0x328 +#define MTK_FE_GDM1_FSM 0x228 +#define MTK_FE_GDM2_FSM 0x22C + +#define MTK_MAC_FSM(x) (0x1010C + ((x) * 0x100)) + struct mtk_rx_dma { unsigned int rxd1; unsigned int rxd2; @@ -970,6 +983,7 @@ struct mtk_reg_map { u32 delay_irq; /* delay interrupt */ u32 irq_status; /* interrupt status */ u32 irq_mask; /* interrupt mask */ + u32 adma_rx_dbg0; u32 int_grp; } pdma; struct { @@ -998,6 +1012,8 @@ struct mtk_reg_map { u32 gdma_to_ppe; u32 ppe_base; u32 wdma_base[2]; + u32 pse_iq_sta; + u32 pse_oq_sta; }; /* struct mtk_eth_data - This is the structure holding all differences @@ -1040,6 +1056,8 @@ struct mtk_soc_data { } txrx; }; +#define MTK_DMA_MONITOR_TIMEOUT msecs_to_jiffies(1000) + /* currently no SoC has more than 2 macs */ #define MTK_MAX_DEVS 2 @@ -1164,6 +1182,14 @@ struct mtk_eth { struct rhashtable flow_table; struct bpf_prog __rcu *prog; + + struct { + struct delayed_work monitor_work; + u32 wdidx; + u8 wdma_hang_count; + u8 qdma_hang_count; + u8 adma_hang_count; + } reset; }; /* struct mtk_mac - the structure that holds the info about the MACs of the From patchwork Mon Jan 2 15:32:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 13086786 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4B849C3DA7A for ; Mon, 2 Jan 2023 15:33:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236413AbjABPdB (ORCPT ); Mon, 2 Jan 2023 10:33:01 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38632 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236416AbjABPcz (ORCPT ); Mon, 2 Jan 2023 10:32:55 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0408AA447 for ; Mon, 2 Jan 2023 07:32:49 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 893476100E for ; Mon, 2 Jan 2023 15:32:48 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 95D85C433D2; Mon, 2 Jan 2023 15:32:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672673567; bh=XC4J8hAgdNklYVa7nljI9pyGv0CWFdpTsv6N9HM514c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GBI8JNi+u9E8VpOgrEwKPEUX7DcExtcGiC5cmHKQ1hctmFLrEzSPh+TnKvvKE0tP0 t/zvjsROyKL6vapf1cVd6ADQNPAZBx+QFuAXWLJRVQHDcucPqn+RUZ9RU6SigZ7A17 IL9k0Rse8LngKKFFaVCTwJB+WqXxvEr+JI/CaGcIzvSxliJd8GuQIfUnupsD/3KAaB r8e9BGqq5eqkpVjxFBbJuxIqtIOX82pyjtcA8FB+XWGyInAMzB5NHJpNxe8CKMFH3s QUMMmkxKzwkvrEGDOQpEzW1Qy9kssLceS1Oby820/D67M/rSwWjOaIsn6gZ6Ft/MW1 cjnEPtjk9TvpQ== From: Lorenzo Bianconi To: netdev@vger.kernel.org Cc: davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, lorenzo.bianconi@redhat.com, nbd@nbd.name, john@phrozen.org, sean.wang@mediatek.com, Mark-MC.Lee@mediatek.com, sujuan.chen@mediatek.com, daniel@makrotopia.org Subject: [PATCH net-next 5/5] net: ethernet: mtk_wed: add reset/reset_complete callbacks Date: Mon, 2 Jan 2023 16:32:19 +0100 Message-Id: <7f699bdb7a93bdc23fd69e9558513eda66887805.1672672965.git.lorenzo@kernel.org> X-Mailer: git-send-email 2.39.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Introduce reset and reset_complete wlan callback to schedule WLAN driver reset when ethernet/wed driver is resetting. Tested-by: Daniel Golle Co-developed-by: Sujuan Chen Signed-off-by: Sujuan Chen Signed-off-by: Lorenzo Bianconi --- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 6 ++++ drivers/net/ethernet/mediatek/mtk_wed.c | 40 +++++++++++++++++++++ drivers/net/ethernet/mediatek/mtk_wed.h | 8 +++++ include/linux/soc/mediatek/mtk_wed.h | 2 ++ 4 files changed, 56 insertions(+) diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c index bafae4f0312e..2d74e26f45c9 100644 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c @@ -3913,6 +3913,10 @@ static void mtk_pending_work(struct work_struct *work) mtk_w32(eth, val, MTK_MAC_MCR(i)); } + rtnl_unlock(); + mtk_wed_fe_reset(); + rtnl_lock(); + /* stop all devices to make sure that dma is properly shut down */ for (i = 0; i < MTK_MAC_COUNT; i++) { if (!eth->netdev[i] || !netif_running(eth->netdev[i])) @@ -3949,6 +3953,8 @@ static void mtk_pending_work(struct work_struct *work) clear_bit(MTK_RESETTING, ð->state); + mtk_wed_fe_reset_complete(); + rtnl_unlock(); } diff --git a/drivers/net/ethernet/mediatek/mtk_wed.c b/drivers/net/ethernet/mediatek/mtk_wed.c index a6271449617f..4854993f2941 100644 --- a/drivers/net/ethernet/mediatek/mtk_wed.c +++ b/drivers/net/ethernet/mediatek/mtk_wed.c @@ -206,6 +206,46 @@ mtk_wed_wo_reset(struct mtk_wed_device *dev) iounmap(reg); } +void mtk_wed_fe_reset(void) +{ + int i; + + mutex_lock(&hw_lock); + + for (i = 0; i < ARRAY_SIZE(hw_list); i++) { + struct mtk_wed_hw *hw = hw_list[i]; + struct mtk_wed_device *dev = hw->wed_dev; + + if (!dev || !dev->wlan.reset) + continue; + + /* reset callback blocks until WLAN reset is completed */ + if (dev->wlan.reset(dev)) + dev_err(dev->dev, "wlan reset failed\n"); + } + + mutex_unlock(&hw_lock); +} + +void mtk_wed_fe_reset_complete(void) +{ + int i; + + mutex_lock(&hw_lock); + + for (i = 0; i < ARRAY_SIZE(hw_list); i++) { + struct mtk_wed_hw *hw = hw_list[i]; + struct mtk_wed_device *dev = hw->wed_dev; + + if (!dev || !dev->wlan.reset_complete) + continue; + + dev->wlan.reset_complete(dev); + } + + mutex_unlock(&hw_lock); +} + static struct mtk_wed_hw * mtk_wed_assign(struct mtk_wed_device *dev) { diff --git a/drivers/net/ethernet/mediatek/mtk_wed.h b/drivers/net/ethernet/mediatek/mtk_wed.h index e012b8a82133..6108a7e69a80 100644 --- a/drivers/net/ethernet/mediatek/mtk_wed.h +++ b/drivers/net/ethernet/mediatek/mtk_wed.h @@ -128,6 +128,8 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth, void mtk_wed_exit(void); int mtk_wed_flow_add(int index); void mtk_wed_flow_remove(int index); +void mtk_wed_fe_reset(void); +void mtk_wed_fe_reset_complete(void); #else static inline void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth, @@ -146,6 +148,12 @@ static inline int mtk_wed_flow_add(int index) static inline void mtk_wed_flow_remove(int index) { } +static inline void mtk_wed_fe_reset(void) +{ +} +static inline void mtk_wed_fe_reset_complete(void) +{ +} #endif diff --git a/include/linux/soc/mediatek/mtk_wed.h b/include/linux/soc/mediatek/mtk_wed.h index db637a13888d..ddff54fc9717 100644 --- a/include/linux/soc/mediatek/mtk_wed.h +++ b/include/linux/soc/mediatek/mtk_wed.h @@ -150,6 +150,8 @@ struct mtk_wed_device { void (*release_rx_buf)(struct mtk_wed_device *wed); void (*update_wo_rx_stats)(struct mtk_wed_device *wed, struct mtk_wed_wo_rx_stats *stats); + int (*reset)(struct mtk_wed_device *wed); + int (*reset_complete)(struct mtk_wed_device *wed); } wlan; #endif };