From patchwork Thu Jul 27 07:15:45 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Feiyang Chen X-Patchwork-Id: 13329045 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2712CC125 for ; Thu, 27 Jul 2023 07:17:37 +0000 (UTC) Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 807B07AA1 for ; Thu, 27 Jul 2023 00:16:58 -0700 (PDT) Received: from loongson.cn (unknown [112.20.109.108]) by gateway (Coremail) with SMTP id _____8Cx5_HBGcJkcpsKAA--.26476S3; Thu, 27 Jul 2023 15:16:17 +0800 (CST) Received: from localhost.localdomain (unknown [112.20.109.108]) by localhost.localdomain (Coremail) with SMTP id AQAAf8DxJ8y8GcJkkrY8AA--.56466S3; Thu, 27 Jul 2023 15:16:13 +0800 (CST) From: Feiyang Chen To: andrew@lunn.ch, hkallweit1@gmail.com, peppe.cavallaro@st.com, alexandre.torgue@foss.st.com, joabreu@synopsys.com, chenhuacai@loongson.cn Cc: Feiyang Chen , linux@armlinux.org.uk, dongbiao@loongson.cn, loongson-kernel@lists.loongnix.cn, netdev@vger.kernel.org, loongarch@lists.linux.dev, chris.chenfeiyang@gmail.com Subject: [PATCH v2 01/10] net: stmmac: Pass stmmac_priv and chan in some callbacks Date: Thu, 27 Jul 2023 15:15:45 +0800 Message-Id: <3aa0b91083da680e8a61bc4afb092fa4a8385673.1690439335.git.chenfeiyang@loongson.cn> X-Mailer: git-send-email 2.39.3 In-Reply-To: References: Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-CM-TRANSID: AQAAf8DxJ8y8GcJkkrY8AA--.56466S3 X-CM-SenderInfo: hfkh0wphl1t03j6o00pqjv00gofq/ X-Coremail-Antispam: 1Uk129KBj9fXoWDXw1kAF45Jry5Cry8tF4kZrc_yoWrWw1kKo WxAFnxt3WSqw18ur97KF18JFy3X3W3Ww1rCrZrCrs5uayxAa1Yvry2qrWfJ3WUXr1fWFW2 va48ta1qyFW7Kw45l-sFpf9Il3svdjkaLaAFLSUrUUUUeb8apTn2vfkv8UJUUUU8wcxFpf 9Il3svdxBIdaVrn0xqx4xG64xvF2IEw4CE5I8CrVC2j2Jv73VFW2AGmfu7bjvjm3AaLaJ3 UjIYCTnIWjp_UUUYC7kC6x804xWl14x267AKxVWUJVW8JwAFc2x0x2IEx4CE42xK8VAvwI 8IcIk0rVWrJVCq3wAFIxvE14AKwVWUXVWUAwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xG Y2AK021l84ACjcxK6xIIjxv20xvE14v26ryj6F1UM28EF7xvwVC0I7IYx2IY6xkF7I0E14 v26r4j6F4UM28EF7xvwVC2z280aVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIEc7CjxVAF wI0_Gr1j6F4UJwAaw2AFwI0_JF0_Jw1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqjxCEc2 xF0cIa020Ex4CE44I27wAqx4xG64xvF2IEw4CE5I8CrVC2j2WlYx0E2Ix0cI8IcVAFwI0_ Jw0_WrylYx0Ex4A2jsIE14v26r4j6F4UMcvjeVCFs4IE7xkEbVWUJVW8JwACjcxG0xvY0x 0EwIxGrwCY1x0262kKe7AKxVWUAVWUtwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkE bVWUJVW8JwCFI7km07C267AKxVWUAVWUtwC20s026c02F40E14v26r1j6r18MI8I3I0E74 80Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcVC0 I7IYx2IY67AKxVW8JVW5JwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Gr0_Cr1lIxAIcVCF04 k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26r4j6F4UMIIF0xvEx4A2jsIEc7Cj xVAFwI0_Gr0_Gr1UYxBIdaVFxhVjvjDU0xZFpf9x07jz5lbUUUUU= X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net X-Patchwork-Delegate: kuba@kernel.org Loongson GMAC and GNET have many extended features. To prepare for that, pass stmmac_priv and chan to more callbacks, and adjust the callbacks accordingly. Signed-off-by: Feiyang Chen --- .../net/ethernet/stmicro/stmmac/chain_mode.c | 5 +- .../net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 20 +++-- .../ethernet/stmicro/stmmac/dwmac1000_core.c | 9 ++- .../ethernet/stmicro/stmmac/dwmac1000_dma.c | 8 +- .../ethernet/stmicro/stmmac/dwmac100_core.c | 9 ++- .../ethernet/stmicro/stmmac/dwmac100_dma.c | 2 +- .../net/ethernet/stmicro/stmmac/dwmac4_core.c | 11 ++- .../ethernet/stmicro/stmmac/dwmac4_descs.c | 19 ++--- .../net/ethernet/stmicro/stmmac/dwmac4_dma.c | 8 +- .../net/ethernet/stmicro/stmmac/dwmac_dma.h | 3 +- .../net/ethernet/stmicro/stmmac/dwmac_lib.c | 3 +- .../ethernet/stmicro/stmmac/dwxgmac2_core.c | 11 ++- .../ethernet/stmicro/stmmac/dwxgmac2_descs.c | 17 ++-- .../ethernet/stmicro/stmmac/dwxgmac2_dma.c | 8 +- .../net/ethernet/stmicro/stmmac/enh_desc.c | 17 ++-- drivers/net/ethernet/stmicro/stmmac/hwif.h | 77 ++++++++++--------- .../net/ethernet/stmicro/stmmac/norm_desc.c | 17 ++-- .../net/ethernet/stmicro/stmmac/ring_mode.c | 4 +- .../net/ethernet/stmicro/stmmac/stmmac_main.c | 6 +- 19 files changed, 145 insertions(+), 109 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c index fb55efd52240..a95866871f3e 100644 --- a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c +++ b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c @@ -95,8 +95,9 @@ static unsigned int is_jumbo_frm(int len, int enh_desc) return ret; } -static void init_dma_chain(void *des, dma_addr_t phy_addr, - unsigned int size, unsigned int extend_desc) +static void init_dma_chain(struct stmmac_priv *priv, void *des, + dma_addr_t phy_addr, unsigned int size, + unsigned int extend_desc) { /* * In chained mode the des3 points to the next element in the ring. diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c index 1e714380d125..e4e1624f81f3 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c @@ -297,7 +297,7 @@ static int sun8i_dwmac_dma_reset(void __iomem *ioaddr) /* sun8i_dwmac_dma_init() - initialize the EMAC * Called from stmmac via stmmac_dma_ops->init */ -static void sun8i_dwmac_dma_init(void __iomem *ioaddr, +static void sun8i_dwmac_dma_init(struct stmmac_priv *priv, void __iomem *ioaddr, struct stmmac_dma_cfg *dma_cfg, int atds) { writel(EMAC_RX_INT | EMAC_TX_INT, ioaddr + EMAC_INT_EN); @@ -394,7 +394,8 @@ static void sun8i_dwmac_dma_start_tx(struct stmmac_priv *priv, writel(v, ioaddr + EMAC_TX_CTL1); } -static void sun8i_dwmac_enable_dma_transmission(void __iomem *ioaddr) +static void sun8i_dwmac_enable_dma_transmission(struct stmmac_priv *priv, + void __iomem *ioaddr, u32 chan) { u32 v; @@ -636,7 +637,8 @@ static void sun8i_dwmac_set_mac(void __iomem *ioaddr, bool enable) * All slot > 0 need to be enabled with MAC_ADDR_TYPE_DST * If addr is NULL, clear the slot */ -static void sun8i_dwmac_set_umac_addr(struct mac_device_info *hw, +static void sun8i_dwmac_set_umac_addr(struct stmmac_priv *priv, + struct mac_device_info *hw, const unsigned char *addr, unsigned int reg_n) { @@ -657,7 +659,8 @@ static void sun8i_dwmac_set_umac_addr(struct mac_device_info *hw, } } -static void sun8i_dwmac_get_umac_addr(struct mac_device_info *hw, +static void sun8i_dwmac_get_umac_addr(struct stmmac_priv *priv, + struct mac_device_info *hw, unsigned char *addr, unsigned int reg_n) { @@ -680,7 +683,8 @@ static int sun8i_dwmac_rx_ipc_enable(struct mac_device_info *hw) return 1; } -static void sun8i_dwmac_set_filter(struct mac_device_info *hw, +static void sun8i_dwmac_set_filter(struct stmmac_priv *priv, + struct mac_device_info *hw, struct net_device *dev) { void __iomem *ioaddr = hw->pcsr; @@ -698,13 +702,13 @@ static void sun8i_dwmac_set_filter(struct mac_device_info *hw, } else if (macaddrs <= hw->unicast_filter_entries) { if (!netdev_mc_empty(dev)) { netdev_for_each_mc_addr(ha, dev) { - sun8i_dwmac_set_umac_addr(hw, ha->addr, i); + sun8i_dwmac_set_umac_addr(priv, hw, ha->addr, i); i++; } } if (!netdev_uc_empty(dev)) { netdev_for_each_uc_addr(ha, dev) { - sun8i_dwmac_set_umac_addr(hw, ha->addr, i); + sun8i_dwmac_set_umac_addr(priv, hw, ha->addr, i); i++; } } @@ -716,7 +720,7 @@ static void sun8i_dwmac_set_filter(struct mac_device_info *hw, /* Disable unused address filter slots */ while (i < hw->unicast_filter_entries) - sun8i_dwmac_set_umac_addr(hw, NULL, i++); + sun8i_dwmac_set_umac_addr(priv, hw, NULL, i++); writel(v, ioaddr + EMAC_RX_FRM_FLT); } diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c index 3927609abc44..b52793edf62f 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c @@ -94,7 +94,8 @@ static void dwmac1000_dump_regs(struct mac_device_info *hw, u32 *reg_space) reg_space[i] = readl(ioaddr + i * 4); } -static void dwmac1000_set_umac_addr(struct mac_device_info *hw, +static void dwmac1000_set_umac_addr(struct stmmac_priv *priv, + struct mac_device_info *hw, const unsigned char *addr, unsigned int reg_n) { @@ -103,7 +104,8 @@ static void dwmac1000_set_umac_addr(struct mac_device_info *hw, GMAC_ADDR_LOW(reg_n)); } -static void dwmac1000_get_umac_addr(struct mac_device_info *hw, +static void dwmac1000_get_umac_addr(struct stmmac_priv *priv, + struct mac_device_info *hw, unsigned char *addr, unsigned int reg_n) { @@ -137,7 +139,8 @@ static void dwmac1000_set_mchash(void __iomem *ioaddr, u32 *mcfilterbits, ioaddr + GMAC_EXTHASH_BASE + regs * 4); } -static void dwmac1000_set_filter(struct mac_device_info *hw, +static void dwmac1000_set_filter(struct stmmac_priv *priv, + struct mac_device_info *hw, struct net_device *dev) { void __iomem *ioaddr = (void __iomem *)dev->base_addr; diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c index daf79cdbd3ec..ce0e6ca6f3a2 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c @@ -16,7 +16,8 @@ #include "dwmac1000.h" #include "dwmac_dma.h" -static void dwmac1000_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi) +static void dwmac1000_dma_axi(struct stmmac_priv *priv, void __iomem *ioaddr, + struct stmmac_axi *axi) { u32 value = readl(ioaddr + DMA_AXI_BUS_MODE); int i; @@ -70,7 +71,7 @@ static void dwmac1000_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi) writel(value, ioaddr + DMA_AXI_BUS_MODE); } -static void dwmac1000_dma_init(void __iomem *ioaddr, +static void dwmac1000_dma_init(struct stmmac_priv *priv, void __iomem *ioaddr, struct stmmac_dma_cfg *dma_cfg, int atds) { u32 value = readl(ioaddr + DMA_BUS_MODE); @@ -223,7 +224,8 @@ static void dwmac1000_dump_dma_regs(struct stmmac_priv *priv, readl(ioaddr + DMA_BUS_MODE + i * 4); } -static int dwmac1000_get_hw_feature(void __iomem *ioaddr, +static int dwmac1000_get_hw_feature(struct stmmac_priv *priv, + void __iomem *ioaddr, struct dma_features *dma_cap) { u32 hw_cap = readl(ioaddr + DMA_HW_FEATURE); diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c index a6e8d7bd9588..c03623edeb75 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c @@ -59,7 +59,8 @@ static int dwmac100_irq_status(struct mac_device_info *hw, return 0; } -static void dwmac100_set_umac_addr(struct mac_device_info *hw, +static void dwmac100_set_umac_addr(struct stmmac_priv *priv, + struct mac_device_info *hw, const unsigned char *addr, unsigned int reg_n) { @@ -67,7 +68,8 @@ static void dwmac100_set_umac_addr(struct mac_device_info *hw, stmmac_set_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW); } -static void dwmac100_get_umac_addr(struct mac_device_info *hw, +static void dwmac100_get_umac_addr(struct stmmac_priv *priv, + struct mac_device_info *hw, unsigned char *addr, unsigned int reg_n) { @@ -75,7 +77,8 @@ static void dwmac100_get_umac_addr(struct mac_device_info *hw, stmmac_get_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW); } -static void dwmac100_set_filter(struct mac_device_info *hw, +static void dwmac100_set_filter(struct stmmac_priv *priv, + struct mac_device_info *hw, struct net_device *dev) { void __iomem *ioaddr = (void __iomem *)dev->base_addr; diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c index 1c32b1788f02..e6ae230fa453 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c @@ -18,7 +18,7 @@ #include "dwmac100.h" #include "dwmac_dma.h" -static void dwmac100_dma_init(void __iomem *ioaddr, +static void dwmac100_dma_init(struct stmmac_priv *priv, void __iomem *ioaddr, struct stmmac_dma_cfg *dma_cfg, int atds) { /* Enable Application Access by writing to DMA CSR0 */ diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c index 03b1c5a97826..536928ccacf9 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c @@ -330,7 +330,8 @@ static void dwmac4_pmt(struct mac_device_info *hw, unsigned long mode) writel(pmt, ioaddr + GMAC_PMT); } -static void dwmac4_set_umac_addr(struct mac_device_info *hw, +static void dwmac4_set_umac_addr(struct stmmac_priv *priv, + struct mac_device_info *hw, const unsigned char *addr, unsigned int reg_n) { void __iomem *ioaddr = hw->pcsr; @@ -339,7 +340,8 @@ static void dwmac4_set_umac_addr(struct mac_device_info *hw, GMAC_ADDR_LOW(reg_n)); } -static void dwmac4_get_umac_addr(struct mac_device_info *hw, +static void dwmac4_get_umac_addr(struct stmmac_priv *priv, + struct mac_device_info *hw, unsigned char *addr, unsigned int reg_n) { void __iomem *ioaddr = hw->pcsr; @@ -588,7 +590,8 @@ static void dwmac4_restore_hw_vlan_rx_fltr(struct net_device *dev, } } -static void dwmac4_set_filter(struct mac_device_info *hw, +static void dwmac4_set_filter(struct stmmac_priv *priv, + struct mac_device_info *hw, struct net_device *dev) { void __iomem *ioaddr = (void __iomem *)dev->base_addr; @@ -664,7 +667,7 @@ static void dwmac4_set_filter(struct mac_device_info *hw, int reg = 1; netdev_for_each_uc_addr(ha, dev) { - dwmac4_set_umac_addr(hw, ha->addr, reg); + dwmac4_set_umac_addr(priv, hw, ha->addr, reg); reg++; } diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c index 6a011d8633e8..98061986c5f4 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c @@ -175,7 +175,7 @@ static int dwmac4_wrback_get_rx_status(struct net_device_stats *stats, return ret; } -static int dwmac4_rd_get_tx_len(struct dma_desc *p) +static int dwmac4_rd_get_tx_len(struct stmmac_priv *priv, struct dma_desc *p) { return (le32_to_cpu(p->des2) & TDES2_BUFFER1_SIZE_MASK); } @@ -296,8 +296,8 @@ static int dwmac4_wrback_get_rx_timestamp_status(void *desc, void *next_desc, return 0; } -static void dwmac4_rd_init_rx_desc(struct dma_desc *p, int disable_rx_ic, - int mode, int end, int bfsize) +static void dwmac4_rd_init_rx_desc(struct stmmac_priv *priv, struct dma_desc *p, + int disable_rx_ic, int mode, int end, int bfsize) { dwmac4_set_rx_owner(p, disable_rx_ic); } @@ -310,9 +310,9 @@ static void dwmac4_rd_init_tx_desc(struct dma_desc *p, int mode, int end) p->des3 = 0; } -static void dwmac4_rd_prepare_tx_desc(struct dma_desc *p, int is_fs, int len, - bool csum_flag, int mode, bool tx_own, - bool ls, unsigned int tot_pkt_len) +static void dwmac4_rd_prepare_tx_desc(struct stmmac_priv *priv, struct dma_desc *p, + int is_fs, int len, bool csum_flag, int mode, + bool tx_own, bool ls, unsigned int tot_pkt_len) { unsigned int tdes3 = le32_to_cpu(p->des3); @@ -462,13 +462,14 @@ static void dwmac4_set_mss_ctxt(struct dma_desc *p, unsigned int mss) p->des3 = cpu_to_le32(TDES3_CONTEXT_TYPE | TDES3_CTXT_TCMSSV); } -static void dwmac4_set_addr(struct dma_desc *p, dma_addr_t addr) +static void dwmac4_set_addr(struct stmmac_priv *priv, struct dma_desc *p, + dma_addr_t addr) { p->des0 = cpu_to_le32(lower_32_bits(addr)); p->des1 = cpu_to_le32(upper_32_bits(addr)); } -static void dwmac4_clear(struct dma_desc *p) +static void dwmac4_clear(struct stmmac_priv *priv, struct dma_desc *p) { p->des0 = 0; p->des1 = 0; @@ -483,7 +484,7 @@ static void dwmac4_set_sarc(struct dma_desc *p, u32 sarc_type) p->des3 |= cpu_to_le32(sarc_type & TDES3_SA_INSERT_CTRL_MASK); } -static int set_16kib_bfsize(int mtu) +static int set_16kib_bfsize(struct stmmac_priv *priv, int mtu) { int ret = 0; diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c index 84d3a8551b03..97dad00dc850 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c @@ -15,7 +15,8 @@ #include "dwmac4_dma.h" #include "stmmac.h" -static void dwmac4_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi) +static void dwmac4_dma_axi(struct stmmac_priv *priv, void __iomem *ioaddr, + struct stmmac_axi *axi) { u32 value = readl(ioaddr + DMA_SYS_BUS_MODE); int i; @@ -152,7 +153,7 @@ static void dwmac410_dma_init_channel(struct stmmac_priv *priv, ioaddr + DMA_CHAN_INTR_ENA(dwmac4_addrs, chan)); } -static void dwmac4_dma_init(void __iomem *ioaddr, +static void dwmac4_dma_init(struct stmmac_priv *priv, void __iomem *ioaddr, struct stmmac_dma_cfg *dma_cfg, int atds) { u32 value = readl(ioaddr + DMA_SYS_BUS_MODE); @@ -374,7 +375,8 @@ static void dwmac4_dma_tx_chan_op_mode(struct stmmac_priv *priv, writel(mtl_tx_op, ioaddr + MTL_CHAN_TX_OP_MODE(dwmac4_addrs, channel)); } -static int dwmac4_get_hw_feature(void __iomem *ioaddr, +static int dwmac4_get_hw_feature(struct stmmac_priv *priv, + void __iomem *ioaddr, struct dma_features *dma_cap) { u32 hw_cap = readl(ioaddr + GMAC_HW_FEATURE0); diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h index 72672391675f..e7aef136824b 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h @@ -152,7 +152,8 @@ #define NUM_DWMAC1000_DMA_REGS 23 #define NUM_DWMAC4_DMA_REGS 27 -void dwmac_enable_dma_transmission(void __iomem *ioaddr); +void dwmac_enable_dma_transmission(struct stmmac_priv *priv, + void __iomem *ioaddr, u32 chan); void dwmac_enable_dma_irq(struct stmmac_priv *priv, void __iomem *ioaddr, u32 chan, bool rx, bool tx); void dwmac_disable_dma_irq(struct stmmac_priv *priv, void __iomem *ioaddr, diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c index 0b6f999a8305..2dd457032187 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c @@ -27,7 +27,8 @@ int dwmac_dma_reset(void __iomem *ioaddr) } /* CSR1 enables the transmit DMA to check for new descriptor */ -void dwmac_enable_dma_transmission(void __iomem *ioaddr) +void dwmac_enable_dma_transmission(struct stmmac_priv *priv, + void __iomem *ioaddr, u32 chan) { writel(1, ioaddr + DMA_XMT_POLL_DEMAND); } diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c index a0c2ef8bb0ac..640c1b4a0c14 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c @@ -337,7 +337,8 @@ static void dwxgmac2_pmt(struct mac_device_info *hw, unsigned long mode) writel(val, ioaddr + XGMAC_PMT); } -static void dwxgmac2_set_umac_addr(struct mac_device_info *hw, +static void dwxgmac2_set_umac_addr(struct stmmac_priv *priv, + struct mac_device_info *hw, const unsigned char *addr, unsigned int reg_n) { @@ -351,7 +352,8 @@ static void dwxgmac2_set_umac_addr(struct mac_device_info *hw, writel(value, ioaddr + XGMAC_ADDRx_LOW(reg_n)); } -static void dwxgmac2_get_umac_addr(struct mac_device_info *hw, +static void dwxgmac2_get_umac_addr(struct stmmac_priv *priv, + struct mac_device_info *hw, unsigned char *addr, unsigned int reg_n) { void __iomem *ioaddr = hw->pcsr; @@ -440,7 +442,8 @@ static void dwxgmac2_set_mchash(void __iomem *ioaddr, u32 *mcfilterbits, writel(mcfilterbits[regs], ioaddr + XGMAC_HASH_TABLE(regs)); } -static void dwxgmac2_set_filter(struct mac_device_info *hw, +static void dwxgmac2_set_filter(struct stmmac_priv *priv, + struct mac_device_info *hw, struct net_device *dev) { void __iomem *ioaddr = (void __iomem *)dev->base_addr; @@ -485,7 +488,7 @@ static void dwxgmac2_set_filter(struct mac_device_info *hw, int reg = 1; netdev_for_each_uc_addr(ha, dev) { - dwxgmac2_set_umac_addr(hw, ha->addr, reg); + dwxgmac2_set_umac_addr(priv, hw, ha->addr, reg); reg++; } diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c index 13c347ee8be9..e6fb47563fc0 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c @@ -41,7 +41,7 @@ static int dwxgmac2_get_rx_status(struct net_device_stats *stats, return good_frame; } -static int dwxgmac2_get_tx_len(struct dma_desc *p) +static int dwxgmac2_get_tx_len(struct stmmac_priv *priv, struct dma_desc *p) { return (le32_to_cpu(p->des2) & XGMAC_TDES2_B1L); } @@ -128,8 +128,8 @@ static int dwxgmac2_get_rx_timestamp_status(void *desc, void *next_desc, return !ret; } -static void dwxgmac2_init_rx_desc(struct dma_desc *p, int disable_rx_ic, - int mode, int end, int bfsize) +static void dwxgmac2_init_rx_desc(struct stmmac_priv *priv, struct dma_desc *p, + int disable_rx_ic, int mode, int end, int bfsize) { dwxgmac2_set_rx_owner(p, disable_rx_ic); } @@ -142,9 +142,9 @@ static void dwxgmac2_init_tx_desc(struct dma_desc *p, int mode, int end) p->des3 = 0; } -static void dwxgmac2_prepare_tx_desc(struct dma_desc *p, int is_fs, int len, - bool csum_flag, int mode, bool tx_own, - bool ls, unsigned int tot_pkt_len) +static void dwxgmac2_prepare_tx_desc(struct stmmac_priv *priv, struct dma_desc *p, + int is_fs, int len, bool csum_flag, int mode, + bool tx_own, bool ls, unsigned int tot_pkt_len) { unsigned int tdes3 = le32_to_cpu(p->des3); @@ -241,13 +241,14 @@ static void dwxgmac2_set_mss(struct dma_desc *p, unsigned int mss) p->des3 = cpu_to_le32(XGMAC_TDES3_CTXT | XGMAC_TDES3_TCMSSV); } -static void dwxgmac2_set_addr(struct dma_desc *p, dma_addr_t addr) +static void dwxgmac2_set_addr(struct stmmac_priv *priv, struct dma_desc *p, + dma_addr_t addr) { p->des0 = cpu_to_le32(lower_32_bits(addr)); p->des1 = cpu_to_le32(upper_32_bits(addr)); } -static void dwxgmac2_clear(struct dma_desc *p) +static void dwxgmac2_clear(struct stmmac_priv *priv, struct dma_desc *p) { p->des0 = 0; p->des1 = 0; diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c index 070bd912580b..08b305f95f97 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c @@ -19,7 +19,7 @@ static int dwxgmac2_dma_reset(void __iomem *ioaddr) !(value & XGMAC_SWR), 0, 100000); } -static void dwxgmac2_dma_init(void __iomem *ioaddr, +static void dwxgmac2_dma_init(struct stmmac_priv *priv, void __iomem *ioaddr, struct stmmac_dma_cfg *dma_cfg, int atds) { u32 value = readl(ioaddr + XGMAC_DMA_SYSBUS_MODE); @@ -81,7 +81,8 @@ static void dwxgmac2_dma_init_tx_chan(struct stmmac_priv *priv, writel(lower_32_bits(phy), ioaddr + XGMAC_DMA_CH_TxDESC_LADDR(chan)); } -static void dwxgmac2_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi) +static void dwxgmac2_dma_axi(struct stmmac_priv *priv, void __iomem *ioaddr, + struct stmmac_axi *axi) { u32 value = readl(ioaddr + XGMAC_DMA_SYSBUS_MODE); int i; @@ -384,7 +385,8 @@ static int dwxgmac2_dma_interrupt(struct stmmac_priv *priv, return ret; } -static int dwxgmac2_get_hw_feature(void __iomem *ioaddr, +static int dwxgmac2_get_hw_feature(struct stmmac_priv *priv, + void __iomem *ioaddr, struct dma_features *dma_cap) { u32 hw_cap; diff --git a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c index a91d8f13a931..1932a3a8e03c 100644 --- a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c +++ b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c @@ -79,7 +79,7 @@ static int enh_desc_get_tx_status(struct net_device_stats *stats, return ret; } -static int enh_desc_get_tx_len(struct dma_desc *p) +static int enh_desc_get_tx_len(struct stmmac_priv *priv, struct dma_desc *p) { return (le32_to_cpu(p->des1) & ETDES1_BUFFER1_SIZE_MASK); } @@ -255,8 +255,8 @@ static int enh_desc_get_rx_status(struct net_device_stats *stats, return ret; } -static void enh_desc_init_rx_desc(struct dma_desc *p, int disable_rx_ic, - int mode, int end, int bfsize) +static void enh_desc_init_rx_desc(struct stmmac_priv *priv, struct dma_desc *p, + int disable_rx_ic, int mode, int end, int bfsize) { int bfsize1; @@ -314,9 +314,9 @@ static void enh_desc_release_tx_desc(struct dma_desc *p, int mode) enh_desc_end_tx_desc_on_ring(p, ter); } -static void enh_desc_prepare_tx_desc(struct dma_desc *p, int is_fs, int len, - bool csum_flag, int mode, bool tx_own, - bool ls, unsigned int tot_pkt_len) +static void enh_desc_prepare_tx_desc(struct stmmac_priv *priv, struct dma_desc *p, + int is_fs, int len, bool csum_flag, int mode, + bool tx_own, bool ls, unsigned int tot_pkt_len) { unsigned int tdes0 = le32_to_cpu(p->des0); @@ -441,12 +441,13 @@ static void enh_desc_display_ring(void *head, unsigned int size, bool rx, pr_info("\n"); } -static void enh_desc_set_addr(struct dma_desc *p, dma_addr_t addr) +static void enh_desc_set_addr(struct stmmac_priv *priv, struct dma_desc *p, + dma_addr_t addr) { p->des2 = cpu_to_le32(addr); } -static void enh_desc_clear(struct dma_desc *p) +static void enh_desc_clear(struct stmmac_priv *priv, struct dma_desc *p) { p->des2 = 0; } diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h index 6ee7cf07cfd7..ed083112c8f1 100644 --- a/drivers/net/ethernet/stmicro/stmmac/hwif.h +++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h @@ -35,14 +35,14 @@ struct dma_edesc; /* Descriptors helpers */ struct stmmac_desc_ops { /* DMA RX descriptor ring initialization */ - void (*init_rx_desc)(struct dma_desc *p, int disable_rx_ic, int mode, - int end, int bfsize); + void (*init_rx_desc)(struct stmmac_priv *priv, struct dma_desc *p, + int disable_rx_ic, int mode, int end, int bfsize); /* DMA TX descriptor ring initialization */ void (*init_tx_desc)(struct dma_desc *p, int mode, int end); /* Invoked by the xmit function to prepare the tx descriptor */ - void (*prepare_tx_desc)(struct dma_desc *p, int is_fs, int len, - bool csum_flag, int mode, bool tx_own, bool ls, - unsigned int tot_pkt_len); + void (*prepare_tx_desc)(struct stmmac_priv *priv, struct dma_desc *p, + int is_fs, int len, bool csum_flag, int mode, + bool tx_own, bool ls, unsigned int tot_pkt_len); void (*prepare_tso_tx_desc)(struct dma_desc *p, int is_fs, int len1, int len2, bool tx_own, bool ls, unsigned int tcphdrlen, unsigned int tcppayloadlen); @@ -61,7 +61,7 @@ struct stmmac_desc_ops { struct stmmac_extra_stats *x, struct dma_desc *p, void __iomem *ioaddr); /* Get the buffer size from the descriptor */ - int (*get_tx_len)(struct dma_desc *p); + int (*get_tx_len)(struct stmmac_priv *priv, struct dma_desc *p); /* Handle extra events on specific interrupts hw dependent */ void (*set_rx_owner)(struct dma_desc *p, int disable_rx_ic); /* Get the receive frame size */ @@ -87,9 +87,10 @@ struct stmmac_desc_ops { /* set MSS via context descriptor */ void (*set_mss)(struct dma_desc *p, unsigned int mss); /* set descriptor skbuff address */ - void (*set_addr)(struct dma_desc *p, dma_addr_t addr); + void (*set_addr)(struct stmmac_priv *priv, struct dma_desc *p, + dma_addr_t addr); /* clear descriptor */ - void (*clear)(struct dma_desc *p); + void (*clear)(struct stmmac_priv *priv, struct dma_desc *p); /* RSS */ int (*get_rx_hash)(struct dma_desc *p, u32 *hash, enum pkt_hash_types *type); @@ -103,11 +104,11 @@ struct stmmac_desc_ops { }; #define stmmac_init_rx_desc(__priv, __args...) \ - stmmac_do_void_callback(__priv, desc, init_rx_desc, __args) + stmmac_do_void_callback(__priv, desc, init_rx_desc, __priv, __args) #define stmmac_init_tx_desc(__priv, __args...) \ stmmac_do_void_callback(__priv, desc, init_tx_desc, __args) #define stmmac_prepare_tx_desc(__priv, __args...) \ - stmmac_do_void_callback(__priv, desc, prepare_tx_desc, __args) + stmmac_do_void_callback(__priv, desc, prepare_tx_desc, __priv, __args) #define stmmac_prepare_tso_tx_desc(__priv, __args...) \ stmmac_do_void_callback(__priv, desc, prepare_tso_tx_desc, __args) #define stmmac_set_tx_owner(__priv, __args...) \ @@ -123,7 +124,7 @@ struct stmmac_desc_ops { #define stmmac_tx_status(__priv, __args...) \ stmmac_do_callback(__priv, desc, tx_status, __args) #define stmmac_get_tx_len(__priv, __args...) \ - stmmac_do_callback(__priv, desc, get_tx_len, __args) + stmmac_do_callback(__priv, desc, get_tx_len, __priv, __args) #define stmmac_set_rx_owner(__priv, __args...) \ stmmac_do_void_callback(__priv, desc, set_rx_owner, __args) #define stmmac_get_rx_frame_len(__priv, __args...) \ @@ -145,9 +146,9 @@ struct stmmac_desc_ops { #define stmmac_set_mss(__priv, __args...) \ stmmac_do_void_callback(__priv, desc, set_mss, __args) #define stmmac_set_desc_addr(__priv, __args...) \ - stmmac_do_void_callback(__priv, desc, set_addr, __args) + stmmac_do_void_callback(__priv, desc, set_addr, __priv, __args) #define stmmac_clear_desc(__priv, __args...) \ - stmmac_do_void_callback(__priv, desc, clear, __args) + stmmac_do_void_callback(__priv, desc, clear, __priv, __args) #define stmmac_get_rx_hash(__priv, __args...) \ stmmac_do_callback(__priv, desc, get_rx_hash, __args) #define stmmac_get_rx_header_len(__priv, __args...) \ @@ -170,8 +171,8 @@ struct dma_features; struct stmmac_dma_ops { /* DMA core initialization */ int (*reset)(void __iomem *ioaddr); - void (*init)(void __iomem *ioaddr, struct stmmac_dma_cfg *dma_cfg, - int atds); + void (*init)(struct stmmac_priv *priv, void __iomem *ioaddr, + struct stmmac_dma_cfg *dma_cfg, int atds); void (*init_chan)(struct stmmac_priv *priv, void __iomem *ioaddr, struct stmmac_dma_cfg *dma_cfg, u32 chan); void (*init_rx_chan)(struct stmmac_priv *priv, void __iomem *ioaddr, @@ -181,7 +182,8 @@ struct stmmac_dma_ops { struct stmmac_dma_cfg *dma_cfg, dma_addr_t phy, u32 chan); /* Configure the AXI Bus Mode Register */ - void (*axi)(void __iomem *ioaddr, struct stmmac_axi *axi); + void (*axi)(struct stmmac_priv *priv, void __iomem *ioaddr, + struct stmmac_axi *axi); /* Dump DMA registers */ void (*dump_regs)(struct stmmac_priv *priv, void __iomem *ioaddr, u32 *reg_space); @@ -194,7 +196,8 @@ struct stmmac_dma_ops { void (*dma_diagnostic_fr)(struct net_device_stats *stats, struct stmmac_extra_stats *x, void __iomem *ioaddr); - void (*enable_dma_transmission) (void __iomem *ioaddr); + void (*enable_dma_transmission)(struct stmmac_priv *priv, + void __iomem *ioaddr, u32 chan); void (*enable_dma_irq)(struct stmmac_priv *priv, void __iomem *ioaddr, u32 chan, bool rx, bool tx); void (*disable_dma_irq)(struct stmmac_priv *priv, void __iomem *ioaddr, @@ -210,7 +213,7 @@ struct stmmac_dma_ops { int (*dma_interrupt)(struct stmmac_priv *priv, void __iomem *ioaddr, struct stmmac_extra_stats *x, u32 chan, u32 dir); /* If supported then get the optional core features */ - int (*get_hw_feature)(void __iomem *ioaddr, + int (*get_hw_feature)(struct stmmac_priv *priv, void __iomem *ioaddr, struct dma_features *dma_cap); /* Program the HW RX Watchdog */ void (*rx_watchdog)(struct stmmac_priv *priv, void __iomem *ioaddr, @@ -236,7 +239,7 @@ struct stmmac_dma_ops { }; #define stmmac_dma_init(__priv, __args...) \ - stmmac_do_void_callback(__priv, dma, init, __args) + stmmac_do_void_callback(__priv, dma, init, __priv, __args) #define stmmac_init_chan(__priv, __args...) \ stmmac_do_void_callback(__priv, dma, init_chan, __priv, __args) #define stmmac_init_rx_chan(__priv, __args...) \ @@ -244,7 +247,7 @@ struct stmmac_dma_ops { #define stmmac_init_tx_chan(__priv, __args...) \ stmmac_do_void_callback(__priv, dma, init_tx_chan, __priv, __args) #define stmmac_axi(__priv, __args...) \ - stmmac_do_void_callback(__priv, dma, axi, __args) + stmmac_do_void_callback(__priv, dma, axi, __priv, __args) #define stmmac_dump_dma_regs(__priv, __args...) \ stmmac_do_void_callback(__priv, dma, dump_regs, __priv, __args) #define stmmac_dma_rx_mode(__priv, __args...) \ @@ -254,7 +257,7 @@ struct stmmac_dma_ops { #define stmmac_dma_diagnostic_fr(__priv, __args...) \ stmmac_do_void_callback(__priv, dma, dma_diagnostic_fr, __args) #define stmmac_enable_dma_transmission(__priv, __args...) \ - stmmac_do_void_callback(__priv, dma, enable_dma_transmission, __args) + stmmac_do_void_callback(__priv, dma, enable_dma_transmission, __priv, __args) #define stmmac_enable_dma_irq(__priv, __args...) \ stmmac_do_void_callback(__priv, dma, enable_dma_irq, __priv, __args) #define stmmac_disable_dma_irq(__priv, __args...) \ @@ -270,7 +273,7 @@ struct stmmac_dma_ops { #define stmmac_dma_interrupt_status(__priv, __args...) \ stmmac_do_callback(__priv, dma, dma_interrupt, __priv, __args) #define stmmac_get_hw_feature(__priv, __args...) \ - stmmac_do_callback(__priv, dma, get_hw_feature, __args) + stmmac_do_callback(__priv, dma, get_hw_feature, __priv, __args) #define stmmac_rx_watchdog(__priv, __args...) \ stmmac_do_void_callback(__priv, dma, rx_watchdog, __priv, __args) #define stmmac_set_tx_ring_len(__priv, __args...) \ @@ -340,17 +343,21 @@ struct stmmac_ops { int (*host_mtl_irq_status)(struct stmmac_priv *priv, struct mac_device_info *hw, u32 chan); /* Multicast filter setting */ - void (*set_filter)(struct mac_device_info *hw, struct net_device *dev); + void (*set_filter)(struct stmmac_priv *priv, struct mac_device_info *hw, + struct net_device *dev); /* Flow control setting */ void (*flow_ctrl)(struct mac_device_info *hw, unsigned int duplex, unsigned int fc, unsigned int pause_time, u32 tx_cnt); /* Set power management mode (e.g. magic frame) */ void (*pmt)(struct mac_device_info *hw, unsigned long mode); /* Set/Get Unicast MAC addresses */ - void (*set_umac_addr)(struct mac_device_info *hw, + void (*set_umac_addr)(struct stmmac_priv *priv, + struct mac_device_info *hw, const unsigned char *addr, unsigned int reg_n); - void (*get_umac_addr)(struct mac_device_info *hw, unsigned char *addr, + void (*get_umac_addr)(struct stmmac_priv *priv, + struct mac_device_info *hw, + unsigned char *addr, unsigned int reg_n); void (*set_eee_mode)(struct mac_device_info *hw, bool en_tx_lpi_clockgating); @@ -452,15 +459,15 @@ struct stmmac_ops { #define stmmac_host_mtl_irq_status(__priv, __args...) \ stmmac_do_callback(__priv, mac, host_mtl_irq_status, __priv, __args) #define stmmac_set_filter(__priv, __args...) \ - stmmac_do_void_callback(__priv, mac, set_filter, __args) + stmmac_do_void_callback(__priv, mac, set_filter, __priv, __args) #define stmmac_flow_ctrl(__priv, __args...) \ stmmac_do_void_callback(__priv, mac, flow_ctrl, __args) #define stmmac_pmt(__priv, __args...) \ stmmac_do_void_callback(__priv, mac, pmt, __args) #define stmmac_set_umac_addr(__priv, __args...) \ - stmmac_do_void_callback(__priv, mac, set_umac_addr, __args) + stmmac_do_void_callback(__priv, mac, set_umac_addr, __priv, __args) #define stmmac_get_umac_addr(__priv, __args...) \ - stmmac_do_void_callback(__priv, mac, get_umac_addr, __args) + stmmac_do_void_callback(__priv, mac, get_umac_addr, __priv, __args) #define stmmac_set_eee_mode(__priv, __args...) \ stmmac_do_void_callback(__priv, mac, set_eee_mode, __args) #define stmmac_reset_eee_mode(__priv, __args...) \ @@ -560,27 +567,27 @@ struct stmmac_rx_queue; /* Helpers to manage the descriptors for chain and ring modes */ struct stmmac_mode_ops { - void (*init) (void *des, dma_addr_t phy_addr, unsigned int size, - unsigned int extend_desc); + void (*init) (struct stmmac_priv *priv, void *des, dma_addr_t phy_addr, + unsigned int size, unsigned int extend_desc); unsigned int (*is_jumbo_frm) (int len, int ehn_desc); int (*jumbo_frm)(struct stmmac_tx_queue *tx_q, struct sk_buff *skb, int csum); - int (*set_16kib_bfsize)(int mtu); - void (*init_desc3)(struct dma_desc *p); + int (*set_16kib_bfsize)(struct stmmac_priv *priv, int mtu); + void (*init_desc3)(struct stmmac_priv *priv, struct dma_desc *p); void (*refill_desc3)(struct stmmac_rx_queue *rx_q, struct dma_desc *p); void (*clean_desc3)(struct stmmac_tx_queue *tx_q, struct dma_desc *p); }; #define stmmac_mode_init(__priv, __args...) \ - stmmac_do_void_callback(__priv, mode, init, __args) + stmmac_do_void_callback(__priv, mode, init, __priv, __args) #define stmmac_is_jumbo_frm(__priv, __args...) \ stmmac_do_callback(__priv, mode, is_jumbo_frm, __args) #define stmmac_jumbo_frm(__priv, __args...) \ stmmac_do_callback(__priv, mode, jumbo_frm, __args) #define stmmac_set_16kib_bfsize(__priv, __args...) \ - stmmac_do_callback(__priv, mode, set_16kib_bfsize, __args) + stmmac_do_callback(__priv, mode, set_16kib_bfsize, __priv, __args) #define stmmac_init_desc3(__priv, __args...) \ - stmmac_do_void_callback(__priv, mode, init_desc3, __args) + stmmac_do_void_callback(__priv, mode, init_desc3, __priv, __args) #define stmmac_refill_desc3(__priv, __args...) \ stmmac_do_void_callback(__priv, mode, refill_desc3, __args) #define stmmac_clean_desc3(__priv, __args...) \ diff --git a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c index 350e6670a576..22b8f27edfab 100644 --- a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c +++ b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c @@ -61,7 +61,7 @@ static int ndesc_get_tx_status(struct net_device_stats *stats, return ret; } -static int ndesc_get_tx_len(struct dma_desc *p) +static int ndesc_get_tx_len(struct stmmac_priv *priv, struct dma_desc *p) { return (le32_to_cpu(p->des1) & RDES1_BUFFER1_SIZE_MASK); } @@ -122,8 +122,8 @@ static int ndesc_get_rx_status(struct net_device_stats *stats, return ret; } -static void ndesc_init_rx_desc(struct dma_desc *p, int disable_rx_ic, int mode, - int end, int bfsize) +static void ndesc_init_rx_desc(struct stmmac_priv *priv, struct dma_desc *p, + int disable_rx_ic, int mode, int end, int bfsize) { int bfsize1; @@ -181,9 +181,9 @@ static void ndesc_release_tx_desc(struct dma_desc *p, int mode) ndesc_end_tx_desc_on_ring(p, ter); } -static void ndesc_prepare_tx_desc(struct dma_desc *p, int is_fs, int len, - bool csum_flag, int mode, bool tx_own, - bool ls, unsigned int tot_pkt_len) +static void ndesc_prepare_tx_desc(struct stmmac_priv *priv, struct dma_desc *p, + int is_fs, int len, bool csum_flag, int mode, + bool tx_own, bool ls, unsigned int tot_pkt_len) { unsigned int tdes1 = le32_to_cpu(p->des1); @@ -292,12 +292,13 @@ static void ndesc_display_ring(void *head, unsigned int size, bool rx, pr_info("\n"); } -static void ndesc_set_addr(struct dma_desc *p, dma_addr_t addr) +static void ndesc_set_addr(struct stmmac_priv *priv, struct dma_desc *p, + dma_addr_t addr) { p->des2 = cpu_to_le32(addr); } -static void ndesc_clear(struct dma_desc *p) +static void ndesc_clear(struct stmmac_priv *priv, struct dma_desc *p) { p->des2 = 0; } diff --git a/drivers/net/ethernet/stmicro/stmmac/ring_mode.c b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c index d218412ca832..49dd6ea07416 100644 --- a/drivers/net/ethernet/stmicro/stmmac/ring_mode.c +++ b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c @@ -111,7 +111,7 @@ static void refill_desc3(struct stmmac_rx_queue *rx_q, struct dma_desc *p) } /* In ring mode we need to fill the desc3 because it is used as buffer */ -static void init_desc3(struct dma_desc *p) +static void init_desc3(struct stmmac_priv *priv, struct dma_desc *p) { p->des3 = cpu_to_le32(le32_to_cpu(p->des2) + BUF_SIZE_8KiB); } @@ -128,7 +128,7 @@ static void clean_desc3(struct stmmac_tx_queue *tx_q, struct dma_desc *p) p->des3 = 0; } -static int set_16kib_bfsize(int mtu) +static int set_16kib_bfsize(struct stmmac_priv *priv, int mtu) { int ret = 0; if (unlikely(mtu > BUF_SIZE_8KiB)) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 4727f7be4f86..e8619853b6d6 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -2499,7 +2499,7 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget) true, priv->mode, true, true, xdp_desc.len); - stmmac_enable_dma_transmission(priv, priv->ioaddr); + stmmac_enable_dma_transmission(priv, priv->ioaddr, queue); tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, priv->dma_conf.dma_tx_size); entry = tx_q->cur_tx; @@ -4559,7 +4559,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) netdev_tx_sent_queue(netdev_get_tx_queue(dev, queue), skb->len); - stmmac_enable_dma_transmission(priv, priv->ioaddr); + stmmac_enable_dma_transmission(priv, priv->ioaddr, queue); stmmac_flush_tx_descriptors(priv, queue); stmmac_tx_timer_arm(priv, queue); @@ -4775,7 +4775,7 @@ static int stmmac_xdp_xmit_xdpf(struct stmmac_priv *priv, int queue, priv->xstats.tx_set_ic_bit++; } - stmmac_enable_dma_transmission(priv, priv->ioaddr); + stmmac_enable_dma_transmission(priv, priv->ioaddr, queue); entry = STMMAC_GET_ENTRY(entry, priv->dma_conf.dma_tx_size); tx_q->cur_tx = entry; From patchwork Thu Jul 27 07:18:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Feiyang Chen X-Patchwork-Id: 13329048 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 020ACC2C8 for ; Thu, 27 Jul 2023 07:18:25 +0000 (UTC) Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 4AFE883C2 for ; Thu, 27 Jul 2023 00:18:11 -0700 (PDT) Received: from loongson.cn (unknown [112.20.109.108]) by gateway (Coremail) with SMTP id _____8BxHOsyGsJkHpwKAA--.21313S3; Thu, 27 Jul 2023 15:18:10 +0800 (CST) Received: from localhost.localdomain (unknown [112.20.109.108]) by localhost.localdomain (Coremail) with SMTP id AQAAf8BxB80wGsJkNLc8AA--.24390S2; Thu, 27 Jul 2023 15:18:09 +0800 (CST) From: Feiyang Chen To: andrew@lunn.ch, hkallweit1@gmail.com, peppe.cavallaro@st.com, alexandre.torgue@foss.st.com, joabreu@synopsys.com, chenhuacai@loongson.cn Cc: Feiyang Chen , linux@armlinux.org.uk, dongbiao@loongson.cn, loongson-kernel@lists.loongnix.cn, netdev@vger.kernel.org, loongarch@lists.linux.dev, chris.chenfeiyang@gmail.com Subject: [PATCH v2 02/10] net: stmmac: dwmac1000: Allow platforms to choose some register offsets Date: Thu, 27 Jul 2023 15:18:04 +0800 Message-Id: <067f87d9785849c13f2f8733d457ffe8616a1aa0.1690439335.git.chenfeiyang@loongson.cn> X-Mailer: git-send-email 2.39.3 In-Reply-To: References: Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-CM-TRANSID: AQAAf8BxB80wGsJkNLc8AA--.24390S2 X-CM-SenderInfo: hfkh0wphl1t03j6o00pqjv00gofq/ X-Coremail-Antispam: 1Uk129KBj9fXoWfGFyUKr48Jw4fWr4UCryrKrX_yoW8WFW8Go ZrJFZIvr48Kw1xCr4DCr1rWr90yr1kJa13Ja1rGrWkZa9agryDGFW5JFyfuF43tryxKF45 Aw1xtF1DA34Yv3Z5l-sFpf9Il3svdjkaLaAFLSUrUUUUeb8apTn2vfkv8UJUUUU8wcxFpf 9Il3svdxBIdaVrn0xqx4xG64xvF2IEw4CE5I8CrVC2j2Jv73VFW2AGmfu7bjvjm3AaLaJ3 UjIYCTnIWjp_UUUYZ7kC6x804xWl14x267AKxVWUJVW8JwAFc2x0x2IEx4CE42xK8VAvwI 8IcIk0rVWrJVCq3wAFIxvE14AKwVWUXVWUAwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xG Y2AK021l84ACjcxK6xIIjxv20xvE14v26F1j6w1UM28EF7xvwVC0I7IYx2IY6xkF7I0E14 v26F4j6r4UJwA2z4x0Y4vEx4A2jsIE14v26r4UJVWxJr1l84ACjcxK6I8E87Iv6xkF7I0E 14v26r4UJVWxJr1ln4kS14v26r126r1DM2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6x kI12xvs2x26I8E6xACxx1l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6xIIjxv20xvE14v2 6rWY6Fy7McIj6I8E87Iv67AKxVW8JVWxJwAm72CE4IkC6x0Yz7v_Jr0_Gr1lF7xvr2IYc2 Ij64vIr41lc7CjxVAaw2AFwI0_JF0_Jw1l42xK82IYc2Ij64vIr41l4I8I3I0E4IkC6x0Y z7v_Jr0_Gr1l4IxYO2xFxVAFwI0_JF0_Jw1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s026x 8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r1q6r43MIIYrxkI7VAKI48JMIIF0xvE 2Ix0cI8IcVAFwI0_Ar0_tr1lIxAIcVC0I7IYx2IY6xkF7I0E14v26r4j6F4UMIIF0xvE42 xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVW8JVWxJwCI42IY6I8E87Iv6xkF 7I0E14v26r4j6r4UJbIYCTnIWIevJa73UjIFyTuYvjxUVWrXDUUUU X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net X-Patchwork-Delegate: kuba@kernel.org Some platforms have dwmac1000 implementations that have a different address space layout than the default. Extend the macro to allow a platform driver to choose the appropriate register offsets. Signed-off-by: Feiyang Chen --- .../ethernet/stmicro/stmmac/dwmac1000_core.c | 14 +- .../ethernet/stmicro/stmmac/dwmac100_core.c | 3 + .../net/ethernet/stmicro/stmmac/dwmac_dma.h | 205 +++++++++--------- .../net/ethernet/stmicro/stmmac/dwmac_lib.c | 41 ++++ include/linux/stmmac.h | 48 ++++ 5 files changed, 210 insertions(+), 101 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c index b52793edf62f..9015a61f804c 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c @@ -19,6 +19,7 @@ #include "stmmac.h" #include "stmmac_pcs.h" #include "dwmac1000.h" +#include "dwmac_dma.h" static void dwmac1000_core_init(struct mac_device_info *hw, struct net_device *dev) @@ -527,12 +528,10 @@ const struct stmmac_ops dwmac1000_ops = { .set_mac_loopback = dwmac1000_set_mac_loopback, }; -int dwmac1000_setup(struct stmmac_priv *priv) +static int _dwmac1000_setup(struct stmmac_priv *priv) { struct mac_device_info *mac = priv->hw; - dev_info(priv->device, "\tDWMAC1000\n"); - priv->dev->priv_flags |= IFF_UNICAST_FLT; mac->pcsr = priv->ioaddr; mac->multicast_filter_bins = priv->plat->multicast_filter_bins; @@ -558,3 +557,12 @@ int dwmac1000_setup(struct stmmac_priv *priv) return 0; } + +int dwmac1000_setup(struct stmmac_priv *priv) +{ + dev_info(priv->device, "\tDWMAC1000\n"); + + priv->plat->dwmac_regs = &dwmac_default_dma_regs; + + return _dwmac1000_setup(priv); +} diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c index c03623edeb75..73ee16549775 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c @@ -18,6 +18,7 @@ #include #include "stmmac.h" #include "dwmac100.h" +#include "dwmac_dma.h" static void dwmac100_core_init(struct mac_device_info *hw, struct net_device *dev) @@ -177,6 +178,8 @@ int dwmac100_setup(struct stmmac_priv *priv) dev_info(priv->device, "\tDWMAC100\n"); + priv->plat->dwmac_regs = &dwmac_default_dma_regs; + mac->pcsr = priv->ioaddr; mac->link.duplex = MAC_CONTROL_F; mac->link.speed10 = 0; diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h index e7aef136824b..915a4d70fd3b 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h @@ -11,38 +11,49 @@ #ifndef __DWMAC_DMA_H__ #define __DWMAC_DMA_H__ -/* DMA CRS Control and Status Register Mapping */ -#define DMA_BUS_MODE 0x00001000 /* Bus Mode */ -#define DMA_XMT_POLL_DEMAND 0x00001004 /* Transmit Poll Demand */ -#define DMA_RCV_POLL_DEMAND 0x00001008 /* Received Poll Demand */ -#define DMA_RCV_BASE_ADDR 0x0000100c /* Receive List Base */ -#define DMA_TX_BASE_ADDR 0x00001010 /* Transmit List Base */ -#define DMA_STATUS 0x00001014 /* Status Register */ -#define DMA_CONTROL 0x00001018 /* Ctrl (Operational Mode) */ -#define DMA_INTR_ENA 0x0000101c /* Interrupt Enable */ -#define DMA_MISSED_FRAME_CTR 0x00001020 /* Missed Frame Counter */ +#include "stmmac.h" -/* SW Reset */ -#define DMA_BUS_MODE_SFT_RESET 0x00000001 /* Software Reset */ +#define _REGS (priv->plat->dwmac_regs) -/* Rx watchdog register */ +/* DMA CRS Control and Status Register Mapping */ +#define DMA_CHAN_OFFSET (_REGS->addrs->chan_offset) +#define DMA_BUS_MODE 0x00001000 +#define DMA_XMT_POLL_DEMAND 0x00001004 +#define DMA_RCV_POLL_DEMAND 0x00001008 +#define DMA_RCV_BASE_ADDR (_REGS->addrs->rcv_base_addr) +#define DMA_RCV_BASE_ADDR_HI (DMA_RCV_BASE_ADDR + 0x4) +#define DMA_TX_BASE_ADDR (_REGS->addrs->tx_base_addr) +#define DMA_TX_BASE_ADDR_HI (DMA_TX_BASE_ADDR + 0x4) +#define DMA_STATUS 0x00001014 +#define DMA_CONTROL 0x00001018 +#define DMA_INTR_ENA 0x0000101c +#define DMA_MISSED_FRAME_CTR 0x00001020 #define DMA_RX_WATCHDOG 0x00001024 - -/* AXI Master Bus Mode */ #define DMA_AXI_BUS_MODE 0x00001028 +#define DMA_HW_FEATURE 0x00001058 +#define DMA_FUNC_CONFIG 0x00001080 +#define DMA_FUNC_CONFIG_HI (DMA_FUNC_CONFIG + 0x4) +#define DMA_CUR_TX_BUF_ADDR (_REGS->addrs->cur_tx_buf_addr) +#define DMA_CUR_TX_BUF_ADDR_HI (DMA_CUR_TX_BUF_ADDR + 0x4) +#define DMA_CUR_RX_BUF_ADDR (_REGS->addrs->cur_rx_buf_addr) +#define DMA_CUR_RX_BUF_ADDR_HI (DMA_CUR_RX_BUF_ADDR + 0x4) +#define DMA_RCV_BASE_ADDR_SHADOW1 0x00001068 +#define DMA_RCV_BASE_ADDR_SHADOW2 0x000010a8 + +/* SW Reset */ +#define DMA_BUS_MODE_SFT_RESET 0x00000001 /* Software Reset */ #define DMA_AXI_EN_LPI BIT(31) #define DMA_AXI_LPI_XIT_FRM BIT(30) -#define DMA_AXI_WR_OSR_LMT GENMASK(23, 20) -#define DMA_AXI_WR_OSR_LMT_SHIFT 20 -#define DMA_AXI_WR_OSR_LMT_MASK 0xf -#define DMA_AXI_RD_OSR_LMT GENMASK(19, 16) -#define DMA_AXI_RD_OSR_LMT_SHIFT 16 -#define DMA_AXI_RD_OSR_LMT_MASK 0xf - -#define DMA_AXI_OSR_MAX 0xf -#define DMA_AXI_MAX_OSR_LIMIT ((DMA_AXI_OSR_MAX << DMA_AXI_WR_OSR_LMT_SHIFT) | \ - (DMA_AXI_OSR_MAX << DMA_AXI_RD_OSR_LMT_SHIFT)) +#define DMA_AXI_WR_OSR_LMT (_REGS->axi->wr_osr_lmt) +#define DMA_AXI_WR_OSR_LMT_SHIFT (_REGS->axi->wr_osr_lmt_shift) +#define DMA_AXI_WR_OSR_LMT_MASK (_REGS->axi->wr_osr_lmt_mask) +#define DMA_AXI_RD_OSR_LMT (_REGS->axi->rd_osr_lmt) +#define DMA_AXI_RD_OSR_LMT_SHIFT (_REGS->axi->rd_osr_lmt_shift) +#define DMA_AXI_RD_OSR_LMT_MASK (_REGS->axi->rd_osr_lmt_mask) +#define DMA_AXI_OSR_MAX (_REGS->axi->osr_max) +#define DMA_AXI_MAX_OSR_LIMIT ((DMA_AXI_OSR_MAX << DMA_AXI_WR_OSR_LMT_SHIFT) | \ + (DMA_AXI_OSR_MAX << DMA_AXI_RD_OSR_LMT_SHIFT)) #define DMA_AXI_1KBBE BIT(13) #define DMA_AXI_AAL BIT(12) #define DMA_AXI_BLEN256 BIT(7) @@ -61,38 +72,30 @@ #define DMA_AXI_BURST_LEN_MASK 0x000000FE -#define DMA_CUR_TX_BUF_ADDR 0x00001050 /* Current Host Tx Buffer */ -#define DMA_CUR_RX_BUF_ADDR 0x00001054 /* Current Host Rx Buffer */ -#define DMA_HW_FEATURE 0x00001058 /* HW Feature Register */ - -/* DMA Control register defines */ -#define DMA_CONTROL_ST 0x00002000 /* Start/Stop Transmission */ -#define DMA_CONTROL_SR 0x00000002 /* Start/Stop Receive */ - /* DMA Normal interrupt */ -#define DMA_INTR_ENA_NIE 0x00010000 /* Normal Summary */ -#define DMA_INTR_ENA_TIE 0x00000001 /* Transmit Interrupt */ -#define DMA_INTR_ENA_TUE 0x00000004 /* Transmit Buffer Unavailable */ -#define DMA_INTR_ENA_RIE 0x00000040 /* Receive Interrupt */ -#define DMA_INTR_ENA_ERE 0x00004000 /* Early Receive */ +#define DMA_INTR_ENA_NIE (_REGS->intr_ena->nie) +#define DMA_INTR_ENA_TIE 0x00000001 +#define DMA_INTR_ENA_TUE 0x00000004 +#define DMA_INTR_ENA_RIE 0x00000040 +#define DMA_INTR_ENA_ERE 0x00004000 -#define DMA_INTR_NORMAL (DMA_INTR_ENA_NIE | DMA_INTR_ENA_RIE | \ - DMA_INTR_ENA_TIE) +#define DMA_INTR_NORMAL (DMA_INTR_ENA_NIE | DMA_INTR_ENA_RIE | \ + DMA_INTR_ENA_TIE) /* DMA Abnormal interrupt */ -#define DMA_INTR_ENA_AIE 0x00008000 /* Abnormal Summary */ -#define DMA_INTR_ENA_FBE 0x00002000 /* Fatal Bus Error */ -#define DMA_INTR_ENA_ETE 0x00000400 /* Early Transmit */ -#define DMA_INTR_ENA_RWE 0x00000200 /* Receive Watchdog */ -#define DMA_INTR_ENA_RSE 0x00000100 /* Receive Stopped */ -#define DMA_INTR_ENA_RUE 0x00000080 /* Receive Buffer Unavailable */ -#define DMA_INTR_ENA_UNE 0x00000020 /* Tx Underflow */ -#define DMA_INTR_ENA_OVE 0x00000010 /* Receive Overflow */ -#define DMA_INTR_ENA_TJE 0x00000008 /* Transmit Jabber */ -#define DMA_INTR_ENA_TSE 0x00000002 /* Transmit Stopped */ +#define DMA_INTR_ENA_AIE (_REGS->intr_ena->aie) +#define DMA_INTR_ENA_FBE 0x00002000 +#define DMA_INTR_ENA_ETE 0x00000400 +#define DMA_INTR_ENA_RWE 0x00000200 +#define DMA_INTR_ENA_RSE 0x00000100 +#define DMA_INTR_ENA_RUE 0x00000080 +#define DMA_INTR_ENA_UNE 0x00000020 +#define DMA_INTR_ENA_OVE 0x00000010 +#define DMA_INTR_ENA_TJE 0x00000008 +#define DMA_INTR_ENA_TSE 0x00000002 #define DMA_INTR_ABNORMAL (DMA_INTR_ENA_AIE | DMA_INTR_ENA_FBE | \ - DMA_INTR_ENA_UNE) + DMA_INTR_ENA_UNE) /* DMA default interrupt mask */ #define DMA_INTR_DEFAULT_MASK (DMA_INTR_NORMAL | DMA_INTR_ABNORMAL) @@ -100,58 +103,64 @@ #define DMA_INTR_DEFAULT_TX (DMA_INTR_ENA_TIE) /* DMA Status register defines */ -#define DMA_STATUS_GLPII 0x40000000 /* GMAC LPI interrupt */ -#define DMA_STATUS_GPI 0x10000000 /* PMT interrupt */ -#define DMA_STATUS_GMI 0x08000000 /* MMC interrupt */ -#define DMA_STATUS_GLI 0x04000000 /* GMAC Line interface int */ -#define DMA_STATUS_EB_MASK 0x00380000 /* Error Bits Mask */ -#define DMA_STATUS_EB_TX_ABORT 0x00080000 /* Error Bits - TX Abort */ -#define DMA_STATUS_EB_RX_ABORT 0x00100000 /* Error Bits - RX Abort */ -#define DMA_STATUS_TS_MASK 0x00700000 /* Transmit Process State */ -#define DMA_STATUS_TS_SHIFT 20 -#define DMA_STATUS_RS_MASK 0x000e0000 /* Receive Process State */ -#define DMA_STATUS_RS_SHIFT 17 -#define DMA_STATUS_NIS 0x00010000 /* Normal Interrupt Summary */ -#define DMA_STATUS_AIS 0x00008000 /* Abnormal Interrupt Summary */ -#define DMA_STATUS_ERI 0x00004000 /* Early Receive Interrupt */ -#define DMA_STATUS_FBI 0x00002000 /* Fatal Bus Error Interrupt */ -#define DMA_STATUS_ETI 0x00000400 /* Early Transmit Interrupt */ -#define DMA_STATUS_RWT 0x00000200 /* Receive Watchdog Timeout */ -#define DMA_STATUS_RPS 0x00000100 /* Receive Process Stopped */ -#define DMA_STATUS_RU 0x00000080 /* Receive Buffer Unavailable */ -#define DMA_STATUS_RI 0x00000040 /* Receive Interrupt */ -#define DMA_STATUS_UNF 0x00000020 /* Transmit Underflow */ -#define DMA_STATUS_OVF 0x00000010 /* Receive Overflow */ -#define DMA_STATUS_TJT 0x00000008 /* Transmit Jabber Timeout */ -#define DMA_STATUS_TU 0x00000004 /* Transmit Buffer Unavailable */ -#define DMA_STATUS_TPS 0x00000002 /* Transmit Process Stopped */ -#define DMA_STATUS_TI 0x00000001 /* Transmit Interrupt */ -#define DMA_CONTROL_FTF 0x00100000 /* Flush transmit FIFO */ - -#define DMA_STATUS_MSK_COMMON (DMA_STATUS_NIS | \ - DMA_STATUS_AIS | \ - DMA_STATUS_FBI) - -#define DMA_STATUS_MSK_RX (DMA_STATUS_ERI | \ - DMA_STATUS_RWT | \ - DMA_STATUS_RPS | \ - DMA_STATUS_RU | \ - DMA_STATUS_RI | \ - DMA_STATUS_OVF | \ - DMA_STATUS_MSK_COMMON) - -#define DMA_STATUS_MSK_TX (DMA_STATUS_ETI | \ - DMA_STATUS_UNF | \ - DMA_STATUS_TJT | \ - DMA_STATUS_TU | \ - DMA_STATUS_TPS | \ - DMA_STATUS_TI | \ - DMA_STATUS_MSK_COMMON) +#define DMA_STATUS_GLPII (_REGS->status->glpii) +#define DMA_STATUS_GPI 0x10000000 +#define DMA_STATUS_GMI 0x08000000 +#define DMA_STATUS_GLI 0x04000000 +#define DMA_STATUS_EB_MASK (_REGS->status->eb_mask) +#define DMA_STATUS_EB_TX_ABORT 0x00080000 +#define DMA_STATUS_EB_RX_ABORT 0x00100000 +#define DMA_STATUS_TS_MASK (_REGS->status->ts_mask) +#define DMA_STATUS_TS_SHIFT (_REGS->status->ts_shift) +#define DMA_STATUS_RS_MASK (_REGS->status->rs_mask) +#define DMA_STATUS_RS_SHIFT (_REGS->status->rs_shift) +#define DMA_STATUS_NIS (_REGS->status->nis) +#define DMA_STATUS_AIS (_REGS->status->ais) +#define DMA_STATUS_ERI 0x00004000 +#define DMA_STATUS_FBI (_REGS->status->fbi) +#define DMA_STATUS_ETI 0x00000400 +#define DMA_STATUS_RWT 0x00000200 +#define DMA_STATUS_RPS 0x00000100 +#define DMA_STATUS_RU 0x00000080 +#define DMA_STATUS_RI 0x00000040 +#define DMA_STATUS_UNF 0x00000020 +#define DMA_STATUS_OVF 0x00000010 +#define DMA_STATUS_TJT 0x00000008 +#define DMA_STATUS_TU 0x00000004 +#define DMA_STATUS_TPS 0x00000002 +#define DMA_STATUS_TI 0x00000001 + +#define DMA_STATUS_MSK_COMMON (DMA_STATUS_NIS | \ + DMA_STATUS_AIS | \ + DMA_STATUS_FBI) + +#define DMA_STATUS_MSK_RX (DMA_STATUS_ERI | \ + DMA_STATUS_RWT | \ + DMA_STATUS_RPS | \ + DMA_STATUS_RU | \ + DMA_STATUS_RI | \ + DMA_STATUS_OVF | \ + DMA_STATUS_MSK_COMMON) + +#define DMA_STATUS_MSK_TX (DMA_STATUS_ETI | \ + DMA_STATUS_UNF | \ + DMA_STATUS_TJT | \ + DMA_STATUS_TU | \ + DMA_STATUS_TPS | \ + DMA_STATUS_TI | \ + DMA_STATUS_MSK_COMMON) + +/* DMA Control register defines */ +#define DMA_CONTROL_ST 0x00002000 /* Start/Stop Transmission */ +#define DMA_CONTROL_SR 0x00000002 /* Start/Stop Receive */ +#define DMA_CONTROL_FTF 0x00100000 /* Flush transmit FIFO */ #define NUM_DWMAC100_DMA_REGS 9 #define NUM_DWMAC1000_DMA_REGS 23 #define NUM_DWMAC4_DMA_REGS 27 +extern const struct dwmac_regs dwmac_default_dma_regs; + void dwmac_enable_dma_transmission(struct stmmac_priv *priv, void __iomem *ioaddr, u32 chan); void dwmac_enable_dma_irq(struct stmmac_priv *priv, void __iomem *ioaddr, diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c index 2dd457032187..266f64148c1a 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c @@ -13,6 +13,47 @@ #define GMAC_HI_REG_AE 0x80000000 +static const struct dwmac_dma_addrs default_dma_addrs = { + .rcv_base_addr = 0x0000100c, + .tx_base_addr = 0x00001010, + .cur_tx_buf_addr = 0x00001050, + .cur_rx_buf_addr = 0x00001054 +}; + +static const struct dwmac_dma_axi default_dma_axi = { + .wr_osr_lmt = GENMASK(23, 20), + .wr_osr_lmt_shift = 20, + .wr_osr_lmt_mask = 0xf, + .rd_osr_lmt = GENMASK(19, 16), + .rd_osr_lmt_shift = 16, + .rd_osr_lmt_mask = 0xf, + .osr_max = 0xf +}; + +static const struct dwmac_dma_intr_ena default_dma_intr_ena = { + .nie = 0x00010000, + .aie = 0x00008000 +}; + +static const struct dwmac_dma_status default_dma_status = { + .glpii = 0x40000000, + .eb_mask = 0x00380000, + .ts_mask = 0x00700000, + .ts_shift = 20, + .rs_mask = 0x000e0000, + .rs_shift = 17, + .nis = 0x00010000, + .ais = 0x00008000, + .fbi = 0x00002000 +}; + +const struct dwmac_regs dwmac_default_dma_regs = { + .addrs = &default_dma_addrs, + .axi = &default_dma_axi, + .intr_ena = &default_dma_intr_ena, + .status = &default_dma_status +}; + int dwmac_dma_reset(void __iomem *ioaddr) { u32 value = readl(ioaddr + DMA_BUS_MODE); diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h index 06090538fe2d..db61dc7c931d 100644 --- a/include/linux/stmmac.h +++ b/include/linux/stmmac.h @@ -204,6 +204,53 @@ struct dwmac4_addrs { u32 mtl_low_cred_offset; }; +/* DMA addresses that may be customized by a platform */ +struct dwmac_dma_addrs { + u32 chan_offset; + u32 rcv_base_addr; + u32 tx_base_addr; + u32 cur_tx_buf_addr; + u32 cur_rx_buf_addr; +}; + +/* DMA AXI registers that may be customized by a platform */ +struct dwmac_dma_axi { + u32 wr_osr_lmt; + u32 wr_osr_lmt_shift; + u32 wr_osr_lmt_mask; + u32 rd_osr_lmt; + u32 rd_osr_lmt_shift; + u32 rd_osr_lmt_mask; + u32 osr_max; +}; + +/* DMA normal and abnormal interrupt that may be customized by a platform */ +struct dwmac_dma_intr_ena { + u32 nie; + u32 aie; +}; + +/* DMA Status register that may be customized by a platform */ +struct dwmac_dma_status { + u32 glpii; + u32 eb_mask; + u32 ts_mask; + u32 ts_shift; + u32 rs_mask; + u32 rs_shift; + u32 nis; + u32 ais; + u32 fbi; +}; + +/* Registers that may be customized by a platform */ +struct dwmac_regs { + const struct dwmac_dma_addrs *addrs; + const struct dwmac_dma_axi *axi; + const struct dwmac_dma_intr_ena *intr_ena; + const struct dwmac_dma_status *status; +}; + struct plat_stmmacenet_data { int bus_id; int phy_addr; @@ -294,5 +341,6 @@ struct plat_stmmacenet_data { bool serdes_up_after_phy_linkup; const struct dwmac4_addrs *dwmac4_addrs; bool has_integrated_pcs; + const struct dwmac_regs *dwmac_regs; }; #endif From patchwork Thu Jul 27 07:15:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Feiyang Chen X-Patchwork-Id: 13329044 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5CF08BE79 for ; Thu, 27 Jul 2023 07:17:29 +0000 (UTC) Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 8A83326B9 for ; Thu, 27 Jul 2023 00:17:02 -0700 (PDT) Received: from loongson.cn (unknown [112.20.109.108]) by gateway (Coremail) with SMTP id _____8AxFvHCGcJke5sKAA--.26362S3; Thu, 27 Jul 2023 15:16:18 +0800 (CST) Received: from localhost.localdomain (unknown [112.20.109.108]) by localhost.localdomain (Coremail) with SMTP id AQAAf8DxJ8y8GcJkkrY8AA--.56466S4; Thu, 27 Jul 2023 15:16:15 +0800 (CST) From: Feiyang Chen To: andrew@lunn.ch, hkallweit1@gmail.com, peppe.cavallaro@st.com, alexandre.torgue@foss.st.com, joabreu@synopsys.com, chenhuacai@loongson.cn Cc: Feiyang Chen , linux@armlinux.org.uk, dongbiao@loongson.cn, loongson-kernel@lists.loongnix.cn, netdev@vger.kernel.org, loongarch@lists.linux.dev, chris.chenfeiyang@gmail.com Subject: [PATCH v2 03/10] net: stmmac: dwmac1000: Add multi-channel support Date: Thu, 27 Jul 2023 15:15:46 +0800 Message-Id: <373259d4ac9ac0b9e1e64ad96d60a9bbd35b85aa.1690439335.git.chenfeiyang@loongson.cn> X-Mailer: git-send-email 2.39.3 In-Reply-To: References: Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-CM-TRANSID: AQAAf8DxJ8y8GcJkkrY8AA--.56466S4 X-CM-SenderInfo: hfkh0wphl1t03j6o00pqjv00gofq/ X-Coremail-Antispam: 1Uk129KBj93XoW3Xr1fAF15GF17ZFW5KF1DXFc_yoWfZrW7pa y5t3s5XFyrtr4fZa1kJws8Xr15J34agrWxuF4fG3yS9a1a9r1agrs0gayjyF13CFZ7Ar9I qrWYvw17Wr1UZrgCm3ZEXasCq-sJn29KB7ZKAUJUUUUf529EdanIXcx71UUUUU7KY7ZEXa sCq-sGcSsGvfJ3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU 0xBIdaVrnRJUUUBIb4IE77IF4wAFF20E14v26r1j6r4UM7CY07I20VC2zVCF04k26cxKx2 IYs7xG6rWj6s0DM7CIcVAFz4kK6r106r15M28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48v e4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_Xr0_Ar1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI 0_Gr0_Cr1l84ACjcxK6I8E87Iv67AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVCY1x0267AK xVW8Jr0_Cr1UM2kKe7AKxVWUAVWUtwAS0I0E0xvYzxvE52x082IY62kv0487Mc804VCY07 AIYIkI8VC2zVCFFI0UMc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7IYx2IY67AKxVWU tVWrXwAv7VC2z280aVAFwI0_Gr0_Cr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0Y48IcxkI7V AKI48JMxkF7I0En4kS14v26r126r1DMxAIw28IcxkI7VAKI48JMxC20s026xCaFVCjc4AY 6r1j6r4UMxCIbckI1I0E14v26r126r1DMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7 xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVWUtVW8ZwCIc40Y0x0EwIxGrwCI42IY6xII jxv20xvE14v26ryj6F1UMIIF0xvE2Ix0cI8IcVCY1x0267AKxVW8JVWxJwCI42IY6xAIw2 0EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Gr0_Cr1lIxAIcVC2z280aVCY1x02 67AKxVW8JVW8JrUvcSsGvfC2KfnxnUUI43ZEXa7IU8KNt3UUUUU== X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net X-Patchwork-Delegate: kuba@kernel.org Some platforms have dwmac1000 implementations that support multi- channel. Extend the functions to add multi-channel support. Signed-off-by: Feiyang Chen --- .../ethernet/stmicro/stmmac/dwmac1000_core.c | 1 + .../ethernet/stmicro/stmmac/dwmac1000_dma.c | 64 +++++++++++++++++-- .../net/ethernet/stmicro/stmmac/dwmac_lib.c | 28 ++++---- include/linux/stmmac.h | 1 + 4 files changed, 73 insertions(+), 21 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c index 9015a61f804c..a9b42a122ed6 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c @@ -562,6 +562,7 @@ int dwmac1000_setup(struct stmmac_priv *priv) { dev_info(priv->device, "\tDWMAC1000\n"); + priv->plat->dwmac_is_loongson = false; priv->plat->dwmac_regs = &dwmac_default_dma_regs; return _dwmac1000_setup(priv); diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c index ce0e6ca6f3a2..efb219999a20 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c @@ -111,13 +111,61 @@ static void dwmac1000_dma_init(struct stmmac_priv *priv, void __iomem *ioaddr, writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA); } +void dwmac1000_dma_init_channel(struct stmmac_priv *priv, void __iomem *ioaddr, + struct stmmac_dma_cfg *dma_cfg, + u32 chan) +{ + u32 value; + int txpbl = dma_cfg->txpbl ?: dma_cfg->pbl; + int rxpbl = dma_cfg->rxpbl ?: dma_cfg->pbl; + + if (!priv->plat->dwmac_is_loongson) + return; + + /* common channel control register config */ + value = readl(ioaddr + DMA_BUS_MODE + chan * DMA_CHAN_OFFSET); + + /* + * Set the DMA PBL (Programmable Burst Length) mode. + * + * Note: before stmmac core 3.50 this mode bit was 4xPBL, and + * post 3.5 mode bit acts as 8*PBL. + */ + if (dma_cfg->pblx8) + value |= DMA_BUS_MODE_MAXPBL; + value |= DMA_BUS_MODE_USP; + value &= ~(DMA_BUS_MODE_PBL_MASK | DMA_BUS_MODE_RPBL_MASK); + value |= (txpbl << DMA_BUS_MODE_PBL_SHIFT); + value |= (rxpbl << DMA_BUS_MODE_RPBL_SHIFT); + + /* Set the Fixed burst mode */ + if (dma_cfg->fixed_burst) + value |= DMA_BUS_MODE_FB; + + /* Mixed Burst has no effect when fb is set */ + if (dma_cfg->mixed_burst) + value |= DMA_BUS_MODE_MB; + + value |= DMA_BUS_MODE_ATDS; + + if (dma_cfg->aal) + value |= DMA_BUS_MODE_AAL; + + writel(value, ioaddr + DMA_BUS_MODE + chan * DMA_CHAN_OFFSET); + + /* Mask interrupts by writing to CSR7 */ + writel(DMA_INTR_DEFAULT_MASK, + ioaddr + DMA_INTR_ENA + chan * DMA_CHAN_OFFSET); +} + static void dwmac1000_dma_init_rx(struct stmmac_priv *priv, void __iomem *ioaddr, struct stmmac_dma_cfg *dma_cfg, dma_addr_t dma_rx_phy, u32 chan) { /* RX descriptor base address list must be written into DMA CSR3 */ - writel(lower_32_bits(dma_rx_phy), ioaddr + DMA_RCV_BASE_ADDR); + writel(lower_32_bits(dma_rx_phy), ioaddr + DMA_RCV_BASE_ADDR + + chan * DMA_CHAN_OFFSET); } static void dwmac1000_dma_init_tx(struct stmmac_priv *priv, @@ -126,7 +174,8 @@ static void dwmac1000_dma_init_tx(struct stmmac_priv *priv, dma_addr_t dma_tx_phy, u32 chan) { /* TX descriptor base address list must be written into DMA CSR4 */ - writel(lower_32_bits(dma_tx_phy), ioaddr + DMA_TX_BASE_ADDR); + writel(lower_32_bits(dma_tx_phy), ioaddr + DMA_TX_BASE_ADDR + + chan * DMA_CHAN_OFFSET); } static u32 dwmac1000_configure_fc(u32 csr6, int rxfifosz) @@ -154,7 +203,7 @@ static void dwmac1000_dma_operation_mode_rx(struct stmmac_priv *priv, void __iomem *ioaddr, int mode, u32 channel, int fifosz, u8 qmode) { - u32 csr6 = readl(ioaddr + DMA_CONTROL); + u32 csr6 = readl(ioaddr + DMA_CONTROL + channel * DMA_CHAN_OFFSET); if (mode == SF_DMA_MODE) { pr_debug("GMAC: enable RX store and forward mode\n"); @@ -176,14 +225,14 @@ static void dwmac1000_dma_operation_mode_rx(struct stmmac_priv *priv, /* Configure flow control based on rx fifo size */ csr6 = dwmac1000_configure_fc(csr6, fifosz); - writel(csr6, ioaddr + DMA_CONTROL); + writel(csr6, ioaddr + DMA_CONTROL + channel * DMA_CHAN_OFFSET); } static void dwmac1000_dma_operation_mode_tx(struct stmmac_priv *priv, void __iomem *ioaddr, int mode, u32 channel, int fifosz, u8 qmode) { - u32 csr6 = readl(ioaddr + DMA_CONTROL); + u32 csr6 = readl(ioaddr + DMA_CONTROL + channel * DMA_CHAN_OFFSET); if (mode == SF_DMA_MODE) { pr_debug("GMAC: enable TX store and forward mode\n"); @@ -210,7 +259,7 @@ static void dwmac1000_dma_operation_mode_tx(struct stmmac_priv *priv, csr6 |= DMA_CONTROL_TTC_256; } - writel(csr6, ioaddr + DMA_CONTROL); + writel(csr6, ioaddr + DMA_CONTROL + channel * DMA_CHAN_OFFSET); } static void dwmac1000_dump_dma_regs(struct stmmac_priv *priv, @@ -273,12 +322,13 @@ static int dwmac1000_get_hw_feature(struct stmmac_priv *priv, static void dwmac1000_rx_watchdog(struct stmmac_priv *priv, void __iomem *ioaddr, u32 riwt, u32 queue) { - writel(riwt, ioaddr + DMA_RX_WATCHDOG); + writel(riwt, ioaddr + DMA_RX_WATCHDOG + queue * DMA_CHAN_OFFSET); } const struct stmmac_dma_ops dwmac1000_dma_ops = { .reset = dwmac_dma_reset, .init = dwmac1000_dma_init, + .init_chan = dwmac1000_dma_init_channel, .init_rx_chan = dwmac1000_dma_init_rx, .init_tx_chan = dwmac1000_dma_init_tx, .axi = dwmac1000_dma_axi, diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c index 266f64148c1a..99838497b183 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c @@ -71,63 +71,63 @@ int dwmac_dma_reset(void __iomem *ioaddr) void dwmac_enable_dma_transmission(struct stmmac_priv *priv, void __iomem *ioaddr, u32 chan) { - writel(1, ioaddr + DMA_XMT_POLL_DEMAND); + writel(1, ioaddr + DMA_XMT_POLL_DEMAND + chan * DMA_CHAN_OFFSET); } void dwmac_enable_dma_irq(struct stmmac_priv *priv, void __iomem *ioaddr, u32 chan, bool rx, bool tx) { - u32 value = readl(ioaddr + DMA_INTR_ENA); + u32 value = readl(ioaddr + DMA_INTR_ENA + chan * DMA_CHAN_OFFSET); if (rx) value |= DMA_INTR_DEFAULT_RX; if (tx) value |= DMA_INTR_DEFAULT_TX; - writel(value, ioaddr + DMA_INTR_ENA); + writel(value, ioaddr + DMA_INTR_ENA + chan * DMA_CHAN_OFFSET); } void dwmac_disable_dma_irq(struct stmmac_priv *priv, void __iomem *ioaddr, u32 chan, bool rx, bool tx) { - u32 value = readl(ioaddr + DMA_INTR_ENA); + u32 value = readl(ioaddr + DMA_INTR_ENA + chan * DMA_CHAN_OFFSET); if (rx) value &= ~DMA_INTR_DEFAULT_RX; if (tx) value &= ~DMA_INTR_DEFAULT_TX; - writel(value, ioaddr + DMA_INTR_ENA); + writel(value, ioaddr + DMA_INTR_ENA + chan * DMA_CHAN_OFFSET); } void dwmac_dma_start_tx(struct stmmac_priv *priv, void __iomem *ioaddr, u32 chan) { - u32 value = readl(ioaddr + DMA_CONTROL); + u32 value = readl(ioaddr + DMA_CONTROL + chan * DMA_CHAN_OFFSET); value |= DMA_CONTROL_ST; - writel(value, ioaddr + DMA_CONTROL); + writel(value, ioaddr + DMA_CONTROL + chan * DMA_CHAN_OFFSET); } void dwmac_dma_stop_tx(struct stmmac_priv *priv, void __iomem *ioaddr, u32 chan) { - u32 value = readl(ioaddr + DMA_CONTROL); + u32 value = readl(ioaddr + DMA_CONTROL + chan * DMA_CHAN_OFFSET); value &= ~DMA_CONTROL_ST; - writel(value, ioaddr + DMA_CONTROL); + writel(value, ioaddr + DMA_CONTROL + chan * DMA_CHAN_OFFSET); } void dwmac_dma_start_rx(struct stmmac_priv *priv, void __iomem *ioaddr, u32 chan) { - u32 value = readl(ioaddr + DMA_CONTROL); + u32 value = readl(ioaddr + DMA_CONTROL + chan * DMA_CHAN_OFFSET); value |= DMA_CONTROL_SR; - writel(value, ioaddr + DMA_CONTROL); + writel(value, ioaddr + DMA_CONTROL + chan * DMA_CHAN_OFFSET); } void dwmac_dma_stop_rx(struct stmmac_priv *priv, void __iomem *ioaddr, u32 chan) { - u32 value = readl(ioaddr + DMA_CONTROL); + u32 value = readl(ioaddr + DMA_CONTROL + chan * DMA_CHAN_OFFSET); value &= ~DMA_CONTROL_SR; - writel(value, ioaddr + DMA_CONTROL); + writel(value, ioaddr + DMA_CONTROL + chan * DMA_CHAN_OFFSET); } #ifdef DWMAC_DMA_DEBUG @@ -205,7 +205,7 @@ int dwmac_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr, { int ret = 0; /* read the status register (CSR5) */ - u32 intr_status = readl(ioaddr + DMA_STATUS); + u32 intr_status = readl(ioaddr + DMA_STATUS + chan * DMA_CHAN_OFFSET); #ifdef DWMAC_DMA_DEBUG /* Enable it to monitor DMA rx/tx status in case of critical problems */ diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h index db61dc7c931d..5e68553433a7 100644 --- a/include/linux/stmmac.h +++ b/include/linux/stmmac.h @@ -342,5 +342,6 @@ struct plat_stmmacenet_data { const struct dwmac4_addrs *dwmac4_addrs; bool has_integrated_pcs; const struct dwmac_regs *dwmac_regs; + bool dwmac_is_loongson; }; #endif From patchwork Thu Jul 27 07:15:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Feiyang Chen X-Patchwork-Id: 13329046 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C8234C2C4 for ; Thu, 27 Jul 2023 07:17:38 +0000 (UTC) Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id EA4817D80 for ; Thu, 27 Jul 2023 00:17:13 -0700 (PDT) Received: from loongson.cn (unknown [112.20.109.108]) by gateway (Coremail) with SMTP id _____8Dx_+vFGcJkiJsKAA--.25449S3; Thu, 27 Jul 2023 15:16:21 +0800 (CST) Received: from localhost.localdomain (unknown [112.20.109.108]) by localhost.localdomain (Coremail) with SMTP id AQAAf8DxJ8y8GcJkkrY8AA--.56466S5; Thu, 27 Jul 2023 15:16:18 +0800 (CST) From: Feiyang Chen To: andrew@lunn.ch, hkallweit1@gmail.com, peppe.cavallaro@st.com, alexandre.torgue@foss.st.com, joabreu@synopsys.com, chenhuacai@loongson.cn Cc: Feiyang Chen , linux@armlinux.org.uk, dongbiao@loongson.cn, loongson-kernel@lists.loongnix.cn, netdev@vger.kernel.org, loongarch@lists.linux.dev, chris.chenfeiyang@gmail.com Subject: [PATCH v2 04/10] net: stmmac: dwmac1000: Add 64-bit DMA support Date: Thu, 27 Jul 2023 15:15:47 +0800 Message-Id: <74a7f82d516836ba53edae509b561f50b441dd63.1690439335.git.chenfeiyang@loongson.cn> X-Mailer: git-send-email 2.39.3 In-Reply-To: References: Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-CM-TRANSID: AQAAf8DxJ8y8GcJkkrY8AA--.56466S5 X-CM-SenderInfo: hfkh0wphl1t03j6o00pqjv00gofq/ X-Coremail-Antispam: 1Uk129KBj9fXoWfJw4DtF47GF1xCw4UGry7CFX_yoW8CFykKo ZrtFnay3yfXw1kX3yDKr1kJrnFqFnxW3s3C3yxC3yku39xZw1Yv3y7W3yrAw4Ykr1aqayU C3W8JFZ7ZFW7Kw1Dl-sFpf9Il3svdjkaLaAFLSUrUUUUeb8apTn2vfkv8UJUUUU8wcxFpf 9Il3svdxBIdaVrn0xqx4xG64xvF2IEw4CE5I8CrVC2j2Jv73VFW2AGmfu7bjvjm3AaLaJ3 UjIYCTnIWjp_UUUYZ7kC6x804xWl14x267AKxVWUJVW8JwAFc2x0x2IEx4CE42xK8VAvwI 8IcIk0rVWrJVCq3wAFIxvE14AKwVWUXVWUAwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xG Y2AK021l84ACjcxK6xIIjxv20xvE14v26F1j6w1UM28EF7xvwVC0I7IYx2IY6xkF7I0E14 v26F4j6r4UJwA2z4x0Y4vEx4A2jsIE14v26r4UJVWxJr1l84ACjcxK6I8E87Iv6xkF7I0E 14v26r4UJVWxJr1ln4kS14v26r126r1DM2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6x kI12xvs2x26I8E6xACxx1l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6xIIjxv20xvE14v2 6rWY6Fy7McIj6I8E87Iv67AKxVW8JVWxJwAm72CE4IkC6x0Yz7v_Jr0_Gr1lF7xvr2IYc2 Ij64vIr41lc7CjxVAaw2AFwI0_JF0_Jw1l42xK82IYc2Ij64vIr41l4I8I3I0E4IkC6x0Y z7v_Jr0_Gr1l4IxYO2xFxVAFwI0_JF0_Jw1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s026x 8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r1q6r43MIIYrxkI7VAKI48JMIIF0xvE 2Ix0cI8IcVAFwI0_Xr0_Ar1lIxAIcVC0I7IYx2IY6xkF7I0E14v26r4j6F4UMIIF0xvE42 xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVW8JVWxJwCI42IY6I8E87Iv6xkF 7I0E14v26r4j6r4UJbIYCTnIWIevJa73UjIFyTuYvjxUVWrXDUUUU X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net X-Patchwork-Delegate: kuba@kernel.org Some platforms have dwmac1000 implementations that support 64-bit DMA. Extend the functions to add 64-bit DMA support. Signed-off-by: Feiyang Chen --- .../net/ethernet/stmicro/stmmac/chain_mode.c | 23 +++- drivers/net/ethernet/stmicro/stmmac/descs.h | 7 ++ .../net/ethernet/stmicro/stmmac/descs_com.h | 49 ++++++--- .../ethernet/stmicro/stmmac/dwmac1000_dma.c | 30 ++++-- .../net/ethernet/stmicro/stmmac/enh_desc.c | 21 +++- .../net/ethernet/stmicro/stmmac/ring_mode.c | 101 ++++++++++++++---- include/linux/stmmac.h | 1 + 7 files changed, 183 insertions(+), 49 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c index a95866871f3e..c8d77cbd51bc 100644 --- a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c +++ b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c @@ -36,6 +36,9 @@ static int jumbo_frm(struct stmmac_tx_queue *tx_q, struct sk_buff *skb, des2 = dma_map_single(priv->device, skb->data, bmax, DMA_TO_DEVICE); desc->des2 = cpu_to_le32(des2); + if (priv->plat->dma_cfg->dma64) + desc->des3 = cpu_to_le32(upper_32_bits(des2)); + if (dma_mapping_error(priv->device, des2)) return -1; tx_q->tx_skbuff_dma[entry].buf = des2; @@ -54,12 +57,16 @@ static int jumbo_frm(struct stmmac_tx_queue *tx_q, struct sk_buff *skb, (skb->data + bmax * i), bmax, DMA_TO_DEVICE); desc->des2 = cpu_to_le32(des2); + if (priv->plat->dma_cfg->dma64) + desc->des3 = cpu_to_le32(upper_32_bits(des2)); if (dma_mapping_error(priv->device, des2)) return -1; tx_q->tx_skbuff_dma[entry].buf = des2; tx_q->tx_skbuff_dma[entry].len = bmax; stmmac_prepare_tx_desc(priv, desc, 0, bmax, csum, - STMMAC_CHAIN_MODE, 1, false, skb->len); + STMMAC_CHAIN_MODE, + !priv->plat->dma_cfg->dma64, + false, skb->len); len -= bmax; i++; } else { @@ -67,6 +74,8 @@ static int jumbo_frm(struct stmmac_tx_queue *tx_q, struct sk_buff *skb, (skb->data + bmax * i), len, DMA_TO_DEVICE); desc->des2 = cpu_to_le32(des2); + if (priv->plat->dma_cfg->dma64) + desc->des3 = cpu_to_le32(upper_32_bits(des2)); if (dma_mapping_error(priv->device, des2)) return -1; tx_q->tx_skbuff_dma[entry].buf = des2; @@ -110,7 +119,11 @@ static void init_dma_chain(struct stmmac_priv *priv, void *des, struct dma_extended_desc *p = (struct dma_extended_desc *)des; for (i = 0; i < (size - 1); i++) { dma_phy += sizeof(struct dma_extended_desc); - p->basic.des3 = cpu_to_le32((unsigned int)dma_phy); + if (priv->plat->dma_cfg->dma64) { + p->des6 = cpu_to_le32((unsigned int)dma_phy); + p->des7 = cpu_to_le32(upper_32_bits(dma_phy)); + } else + p->basic.des3 = cpu_to_le32((unsigned int)dma_phy); p++; } p->basic.des3 = cpu_to_le32((unsigned int)phy_addr); @@ -130,6 +143,9 @@ static void refill_desc3(struct stmmac_rx_queue *rx_q, struct dma_desc *p) { struct stmmac_priv *priv = rx_q->priv_data; + if (priv->plat->dma_cfg->dma64) + return; + if (priv->hwts_rx_en && !priv->extend_desc) /* NOTE: Device will overwrite des3 with timestamp value if * 1588-2002 time stamping is enabled, hence reinitialize it @@ -146,6 +162,9 @@ static void clean_desc3(struct stmmac_tx_queue *tx_q, struct dma_desc *p) struct stmmac_priv *priv = tx_q->priv_data; unsigned int entry = tx_q->dirty_tx; + if (priv->plat->dma_cfg->dma64) + return; + if (tx_q->tx_skbuff_dma[entry].last_segment && !priv->extend_desc && priv->hwts_tx_en) /* NOTE: Device will overwrite des3 with timestamp value if diff --git a/drivers/net/ethernet/stmicro/stmmac/descs.h b/drivers/net/ethernet/stmicro/stmmac/descs.h index 49d6a866244f..223b77f0271c 100644 --- a/drivers/net/ethernet/stmicro/stmmac/descs.h +++ b/drivers/net/ethernet/stmicro/stmmac/descs.h @@ -56,6 +56,9 @@ #define ERDES1_BUFFER2_SIZE_SHIFT 16 #define ERDES1_DISABLE_IC BIT(31) +#define E64RDES1_BUFFER1_SIZE_MASK GENMASK(13, 0) +#define E64RDES1_BUFFER2_SIZE_MASK GENMASK(29, 16) + /* Normal transmit descriptor defines */ /* TDES0 */ #define TDES0_DEFERRED BIT(0) @@ -122,6 +125,10 @@ #define ETDES1_BUFFER2_SIZE_MASK GENMASK(28, 16) #define ETDES1_BUFFER2_SIZE_SHIFT 16 +#define E64TDES1_BUFFER1_SIZE_MASK GENMASK(13, 0) +#define E64TDES1_BUFFER2_SIZE_MASK GENMASK(28, 15) +#define E64TDES1_BUFFER2_SIZE_SHIFT 15 + /* Extended Receive descriptor definitions */ #define ERDES4_IP_PAYLOAD_TYPE_MASK GENMASK(6, 2) #define ERDES4_IP_HDR_ERR BIT(3) diff --git a/drivers/net/ethernet/stmicro/stmmac/descs_com.h b/drivers/net/ethernet/stmicro/stmmac/descs_com.h index 40f7f2da9c5e..c5e7f2e5aee8 100644 --- a/drivers/net/ethernet/stmicro/stmmac/descs_com.h +++ b/drivers/net/ethernet/stmicro/stmmac/descs_com.h @@ -20,12 +20,18 @@ /* Enhanced descriptors */ static inline void ehn_desc_rx_set_on_ring(struct dma_desc *p, int end, - int bfsize) + int bfsize, bool dma64) { - if (bfsize == BUF_SIZE_16KiB) - p->des1 |= cpu_to_le32((BUF_SIZE_8KiB - << ERDES1_BUFFER2_SIZE_SHIFT) - & ERDES1_BUFFER2_SIZE_MASK); + if (bfsize == BUF_SIZE_16KiB) { + if (dma64) + p->des1 |= cpu_to_le32((BUF_SIZE_8KiB + << ERDES1_BUFFER2_SIZE_SHIFT) + & E64RDES1_BUFFER2_SIZE_MASK); + else + p->des1 |= cpu_to_le32((BUF_SIZE_8KiB + << ERDES1_BUFFER2_SIZE_SHIFT) + & ERDES1_BUFFER2_SIZE_MASK); + } if (end) p->des1 |= cpu_to_le32(ERDES1_END_RING); @@ -39,15 +45,26 @@ static inline void enh_desc_end_tx_desc_on_ring(struct dma_desc *p, int end) p->des0 &= cpu_to_le32(~ETDES0_END_RING); } -static inline void enh_set_tx_desc_len_on_ring(struct dma_desc *p, int len) +static inline void enh_set_tx_desc_len_on_ring(struct dma_desc *p, int len, + bool dma64) { if (unlikely(len > BUF_SIZE_4KiB)) { - p->des1 |= cpu_to_le32((((len - BUF_SIZE_4KiB) - << ETDES1_BUFFER2_SIZE_SHIFT) - & ETDES1_BUFFER2_SIZE_MASK) | (BUF_SIZE_4KiB - & ETDES1_BUFFER1_SIZE_MASK)); - } else - p->des1 |= cpu_to_le32((len & ETDES1_BUFFER1_SIZE_MASK)); + if (dma64) + p->des1 |= cpu_to_le32((((len - BUF_SIZE_8KiB) + << E64TDES1_BUFFER2_SIZE_SHIFT) + & E64TDES1_BUFFER2_SIZE_MASK) | (BUF_SIZE_8KiB + & E64TDES1_BUFFER1_SIZE_MASK)); + else + p->des1 |= cpu_to_le32((((len - BUF_SIZE_4KiB) + << ETDES1_BUFFER2_SIZE_SHIFT) + & ETDES1_BUFFER2_SIZE_MASK) | (BUF_SIZE_4KiB + & ETDES1_BUFFER1_SIZE_MASK)); + } else { + if (dma64) + p->des1 |= cpu_to_le32((len & E64TDES1_BUFFER1_SIZE_MASK)); + else + p->des1 |= cpu_to_le32((len & ETDES1_BUFFER1_SIZE_MASK)); + } } /* Normal descriptors */ @@ -98,9 +115,13 @@ static inline void enh_desc_end_tx_desc_on_chain(struct dma_desc *p) p->des0 |= cpu_to_le32(ETDES0_SECOND_ADDRESS_CHAINED); } -static inline void enh_set_tx_desc_len_on_chain(struct dma_desc *p, int len) +static inline void enh_set_tx_desc_len_on_chain(struct dma_desc *p, int len, + bool dma64) { - p->des1 |= cpu_to_le32(len & ETDES1_BUFFER1_SIZE_MASK); + if (dma64) + p->des1 |= cpu_to_le32(len & E64TDES1_BUFFER1_SIZE_MASK); + else + p->des1 |= cpu_to_le32(len & ETDES1_BUFFER1_SIZE_MASK); } /* Normal descriptors */ diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c index efb219999a20..632c4f110d01 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c @@ -15,6 +15,7 @@ #include #include "dwmac1000.h" #include "dwmac_dma.h" +#include "stmmac.h" static void dwmac1000_dma_axi(struct stmmac_priv *priv, void __iomem *ioaddr, struct stmmac_axi *axi) @@ -109,6 +110,9 @@ static void dwmac1000_dma_init(struct stmmac_priv *priv, void __iomem *ioaddr, /* Mask interrupts by writing to CSR7 */ writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA); + + if (dma_cfg->dma64) + writel(0x100, ioaddr + DMA_FUNC_CONFIG); } void dwmac1000_dma_init_channel(struct stmmac_priv *priv, void __iomem *ioaddr, @@ -163,9 +167,16 @@ static void dwmac1000_dma_init_rx(struct stmmac_priv *priv, struct stmmac_dma_cfg *dma_cfg, dma_addr_t dma_rx_phy, u32 chan) { - /* RX descriptor base address list must be written into DMA CSR3 */ - writel(lower_32_bits(dma_rx_phy), ioaddr + DMA_RCV_BASE_ADDR + - chan * DMA_CHAN_OFFSET); + if (dma_cfg->dma64) { + writel(lower_32_bits(dma_rx_phy), ioaddr + DMA_RCV_BASE_ADDR + + chan * DMA_CHAN_OFFSET); + writel(upper_32_bits(dma_rx_phy), ioaddr + DMA_RCV_BASE_ADDR_HI + + chan * DMA_CHAN_OFFSET); + } else { + /* RX descriptor base address list must be written into DMA CSR3 */ + writel(lower_32_bits(dma_rx_phy), ioaddr + DMA_RCV_BASE_ADDR + + chan * DMA_CHAN_OFFSET); + } } static void dwmac1000_dma_init_tx(struct stmmac_priv *priv, @@ -173,9 +184,16 @@ static void dwmac1000_dma_init_tx(struct stmmac_priv *priv, struct stmmac_dma_cfg *dma_cfg, dma_addr_t dma_tx_phy, u32 chan) { - /* TX descriptor base address list must be written into DMA CSR4 */ - writel(lower_32_bits(dma_tx_phy), ioaddr + DMA_TX_BASE_ADDR + - chan * DMA_CHAN_OFFSET); + if (dma_cfg->dma64) { + writel(lower_32_bits(dma_tx_phy), ioaddr + DMA_TX_BASE_ADDR + + chan * DMA_CHAN_OFFSET); + writel(upper_32_bits(dma_tx_phy), ioaddr + DMA_TX_BASE_ADDR_HI + + chan * DMA_CHAN_OFFSET); + } else { + /* TX descriptor base address list must be written into DMA CSR4 */ + writel(lower_32_bits(dma_tx_phy), ioaddr + DMA_TX_BASE_ADDR + + chan * DMA_CHAN_OFFSET); + } } static u32 dwmac1000_configure_fc(u32 csr6, int rxfifosz) diff --git a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c index 1932a3a8e03c..ee07006c97c1 100644 --- a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c +++ b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c @@ -11,6 +11,7 @@ #include #include "common.h" #include "descs_com.h" +#include "stmmac.h" static int enh_desc_get_tx_status(struct net_device_stats *stats, struct stmmac_extra_stats *x, @@ -81,7 +82,10 @@ static int enh_desc_get_tx_status(struct net_device_stats *stats, static int enh_desc_get_tx_len(struct stmmac_priv *priv, struct dma_desc *p) { - return (le32_to_cpu(p->des1) & ETDES1_BUFFER1_SIZE_MASK); + if (priv->plat->dma_cfg->dma64) + return (le32_to_cpu(p->des1) & E64TDES1_BUFFER1_SIZE_MASK); + else + return (le32_to_cpu(p->des1) & ETDES1_BUFFER1_SIZE_MASK); } static int enh_desc_coe_rdes0(int ipc_err, int type, int payload_err) @@ -263,12 +267,15 @@ static void enh_desc_init_rx_desc(struct stmmac_priv *priv, struct dma_desc *p, p->des0 |= cpu_to_le32(RDES0_OWN); bfsize1 = min(bfsize, BUF_SIZE_8KiB); - p->des1 |= cpu_to_le32(bfsize1 & ERDES1_BUFFER1_SIZE_MASK); + if (priv->plat->dma_cfg->dma64) + p->des1 |= cpu_to_le32(bfsize1 & E64RDES1_BUFFER1_SIZE_MASK); + else + p->des1 |= cpu_to_le32(bfsize1 & ERDES1_BUFFER1_SIZE_MASK); if (mode == STMMAC_CHAIN_MODE) ehn_desc_rx_set_on_chain(p); else - ehn_desc_rx_set_on_ring(p, end, bfsize); + ehn_desc_rx_set_on_ring(p, end, bfsize, priv->plat->dma_cfg->dma64); if (disable_rx_ic) p->des1 |= cpu_to_le32(ERDES1_DISABLE_IC); @@ -321,9 +328,9 @@ static void enh_desc_prepare_tx_desc(struct stmmac_priv *priv, struct dma_desc * unsigned int tdes0 = le32_to_cpu(p->des0); if (mode == STMMAC_CHAIN_MODE) - enh_set_tx_desc_len_on_chain(p, len); + enh_set_tx_desc_len_on_chain(p, len, priv->plat->dma_cfg->dma64); else - enh_set_tx_desc_len_on_ring(p, len); + enh_set_tx_desc_len_on_ring(p, len, priv->plat->dma_cfg->dma64); if (is_fs) tdes0 |= ETDES0_FIRST_SEGMENT; @@ -445,11 +452,15 @@ static void enh_desc_set_addr(struct stmmac_priv *priv, struct dma_desc *p, dma_addr_t addr) { p->des2 = cpu_to_le32(addr); + if (priv->plat->dma_cfg->dma64) + p->des3 = cpu_to_le32(upper_32_bits(addr)); } static void enh_desc_clear(struct stmmac_priv *priv, struct dma_desc *p) { p->des2 = 0; + if (priv->plat->dma_cfg->dma64) + p->des3 = 0; } const struct stmmac_desc_ops enh_desc_ops = { diff --git a/drivers/net/ethernet/stmicro/stmmac/ring_mode.c b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c index 49dd6ea07416..2b664a51a4f7 100644 --- a/drivers/net/ethernet/stmicro/stmmac/ring_mode.c +++ b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c @@ -21,10 +21,14 @@ static int jumbo_frm(struct stmmac_tx_queue *tx_q, struct sk_buff *skb, struct stmmac_priv *priv = tx_q->priv_data; unsigned int entry = tx_q->cur_tx; unsigned int bmax, len, des2; + unsigned int bmax2, len2; + struct dma_extended_desc *edesc; struct dma_desc *desc; - if (priv->extend_desc) - desc = (struct dma_desc *)(tx_q->dma_etx + entry); + if (priv->extend_desc) { + edesc = tx_q->dma_etx + entry; + desc = (struct dma_desc *)edesc; + } else desc = tx_q->dma_tx + entry; @@ -33,23 +37,37 @@ static int jumbo_frm(struct stmmac_tx_queue *tx_q, struct sk_buff *skb, else bmax = BUF_SIZE_2KiB; - len = nopaged_len - bmax; + if (priv->plat->dma_cfg->dma64) { + bmax2 = bmax * 2; + len2 = bmax2; + } else { + bmax2 = bmax; + len2 = BUF_SIZE_8KiB; + } + len = nopaged_len - bmax2; - if (nopaged_len > BUF_SIZE_8KiB) { + if (nopaged_len > len2) { - des2 = dma_map_single(priv->device, skb->data, bmax, + des2 = dma_map_single(priv->device, skb->data, bmax2, DMA_TO_DEVICE); desc->des2 = cpu_to_le32(des2); + if (priv->plat->dma_cfg->dma64) + desc->des3 = cpu_to_le32(upper_32_bits(des2)); if (dma_mapping_error(priv->device, des2)) return -1; tx_q->tx_skbuff_dma[entry].buf = des2; - tx_q->tx_skbuff_dma[entry].len = bmax; + tx_q->tx_skbuff_dma[entry].len = bmax2; tx_q->tx_skbuff_dma[entry].is_jumbo = true; - desc->des3 = cpu_to_le32(des2 + BUF_SIZE_4KiB); + if (priv->plat->dma_cfg->dma64) { + edesc->des6 = cpu_to_le32(des2 + bmax); + edesc->des7 = cpu_to_le32(upper_32_bits(edesc->des6)); + } else + desc->des3 = cpu_to_le32(des2 + BUF_SIZE_4KiB); stmmac_prepare_tx_desc(priv, desc, 1, bmax, csum, - STMMAC_RING_MODE, 0, false, skb->len); + STMMAC_RING_MODE, priv->plat->dma_cfg->dma64, + false, skb->len); tx_q->tx_skbuff[entry] = NULL; entry = STMMAC_GET_ENTRY(entry, priv->dma_conf.dma_tx_size); @@ -61,13 +79,19 @@ static int jumbo_frm(struct stmmac_tx_queue *tx_q, struct sk_buff *skb, des2 = dma_map_single(priv->device, skb->data + bmax, len, DMA_TO_DEVICE); desc->des2 = cpu_to_le32(des2); + if (priv->plat->dma_cfg->dma64) + desc->des3 = cpu_to_le32(upper_32_bits(des2)); if (dma_mapping_error(priv->device, des2)) return -1; tx_q->tx_skbuff_dma[entry].buf = des2; tx_q->tx_skbuff_dma[entry].len = len; tx_q->tx_skbuff_dma[entry].is_jumbo = true; - desc->des3 = cpu_to_le32(des2 + BUF_SIZE_4KiB); + if (priv->plat->dma_cfg->dma64) { + edesc->des6 = cpu_to_le32(des2 + bmax); + edesc->des7 = cpu_to_le32(upper_32_bits(edesc->des6)); + } else + desc->des3 = cpu_to_le32(des2 + BUF_SIZE_4KiB); stmmac_prepare_tx_desc(priv, desc, 0, len, csum, STMMAC_RING_MODE, 1, !skb_is_nonlinear(skb), skb->len); @@ -82,8 +106,8 @@ static int jumbo_frm(struct stmmac_tx_queue *tx_q, struct sk_buff *skb, tx_q->tx_skbuff_dma[entry].is_jumbo = true; desc->des3 = cpu_to_le32(des2 + BUF_SIZE_4KiB); stmmac_prepare_tx_desc(priv, desc, 1, nopaged_len, csum, - STMMAC_RING_MODE, 0, !skb_is_nonlinear(skb), - skb->len); + STMMAC_RING_MODE, priv->plat->dma_cfg->dma64, + !skb_is_nonlinear(skb), skb->len); } tx_q->cur_tx = entry; @@ -103,36 +127,69 @@ static unsigned int is_jumbo_frm(int len, int enh_desc) static void refill_desc3(struct stmmac_rx_queue *rx_q, struct dma_desc *p) { + struct dma_extended_desc *edesc = (struct dma_extended_desc *)p; struct stmmac_priv *priv = rx_q->priv_data; - /* Fill DES3 in case of RING mode */ - if (priv->dma_conf.dma_buf_sz == BUF_SIZE_16KiB) - p->des3 = cpu_to_le32(le32_to_cpu(p->des2) + BUF_SIZE_8KiB); + if (priv->plat->dma_cfg->dma64) { + if (priv->dma_conf.dma_buf_sz >= BUF_SIZE_8KiB) { + edesc->des6 = cpu_to_le32(le32_to_cpu(edesc->basic.des2) + + BUF_SIZE_8KiB); + edesc->des7 = cpu_to_le32(le32_to_cpu(edesc->basic.des3)); + } + } else { + /* Fill DES3 in case of RING mode */ + if (priv->dma_conf.dma_buf_sz == BUF_SIZE_16KiB) + p->des3 = cpu_to_le32(le32_to_cpu(p->des2) + + BUF_SIZE_8KiB); + } } /* In ring mode we need to fill the desc3 because it is used as buffer */ static void init_desc3(struct stmmac_priv *priv, struct dma_desc *p) { - p->des3 = cpu_to_le32(le32_to_cpu(p->des2) + BUF_SIZE_8KiB); + struct dma_extended_desc *edesc = (struct dma_extended_desc *)p; + + if (priv->plat->dma_cfg->dma64) { + edesc->des6 = cpu_to_le32(le32_to_cpu(edesc->basic.des2) + + BUF_SIZE_8KiB); + edesc->des7 = cpu_to_le32(le32_to_cpu(edesc->basic.des3)); + } else + p->des3 = cpu_to_le32(le32_to_cpu(p->des2) + + BUF_SIZE_8KiB); } static void clean_desc3(struct stmmac_tx_queue *tx_q, struct dma_desc *p) { + struct dma_extended_desc *edesc = (struct dma_extended_desc *)p; struct stmmac_priv *priv = tx_q->priv_data; unsigned int entry = tx_q->dirty_tx; - /* des3 is only used for jumbo frames tx or time stamping */ - if (unlikely(tx_q->tx_skbuff_dma[entry].is_jumbo || - (tx_q->tx_skbuff_dma[entry].last_segment && - !priv->extend_desc && priv->hwts_tx_en))) - p->des3 = 0; + if (priv->plat->dma_cfg->dma64) { + if (unlikely(tx_q->tx_skbuff_dma[entry].is_jumbo)) { + edesc->des6 = 0; + edesc->des7 = 0; + } + } else { + /* des3 is only used for jumbo frames tx or time stamping */ + if (unlikely(tx_q->tx_skbuff_dma[entry].is_jumbo || + (tx_q->tx_skbuff_dma[entry].last_segment && + !priv->extend_desc && priv->hwts_tx_en))) + p->des3 = 0; + } } static int set_16kib_bfsize(struct stmmac_priv *priv, int mtu) { int ret = 0; - if (unlikely(mtu > BUF_SIZE_8KiB)) - ret = BUF_SIZE_16KiB; + + if (priv->plat->dma_cfg->dma64) { + if (unlikely(mtu >= BUF_SIZE_8KiB)) + ret = BUF_SIZE_16KiB; + } else { + if (unlikely(mtu > BUF_SIZE_8KiB)) + ret = BUF_SIZE_16KiB; + } + return ret; } diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h index 5e68553433a7..46bccc34814d 100644 --- a/include/linux/stmmac.h +++ b/include/linux/stmmac.h @@ -98,6 +98,7 @@ struct stmmac_dma_cfg { bool eame; bool multi_msi_en; bool dche; + bool dma64; }; #define AXI_BLEN 7 From patchwork Thu Jul 27 07:18:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Feiyang Chen X-Patchwork-Id: 13329047 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A9C4EC142 for ; Thu, 27 Jul 2023 07:18:25 +0000 (UTC) Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 6766F83CA for ; Thu, 27 Jul 2023 00:18:13 -0700 (PDT) Received: from loongson.cn (unknown [112.20.109.108]) by gateway (Coremail) with SMTP id _____8BxyeozGsJkJ5wKAA--.16887S3; Thu, 27 Jul 2023 15:18:11 +0800 (CST) Received: from localhost.localdomain (unknown [112.20.109.108]) by localhost.localdomain (Coremail) with SMTP id AQAAf8BxB80wGsJkNLc8AA--.24390S3; Thu, 27 Jul 2023 15:18:10 +0800 (CST) From: Feiyang Chen To: andrew@lunn.ch, hkallweit1@gmail.com, peppe.cavallaro@st.com, alexandre.torgue@foss.st.com, joabreu@synopsys.com, chenhuacai@loongson.cn Cc: Feiyang Chen , linux@armlinux.org.uk, dongbiao@loongson.cn, loongson-kernel@lists.loongnix.cn, netdev@vger.kernel.org, loongarch@lists.linux.dev, chris.chenfeiyang@gmail.com Subject: [PATCH v2 05/10] net: stmmac: dwmac1000: Add Loongson register definitions Date: Thu, 27 Jul 2023 15:18:05 +0800 Message-Id: X-Mailer: git-send-email 2.39.3 In-Reply-To: References: Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-CM-TRANSID: AQAAf8BxB80wGsJkNLc8AA--.24390S3 X-CM-SenderInfo: hfkh0wphl1t03j6o00pqjv00gofq/ X-Coremail-Antispam: 1Uk129KBj93XoW3uw1kur47CF47ur1rJw4fWFX_yoWkWr15pa y7Aa45GrW8tF45Za1kJr48XFy5Z3yYkFW7ur4xKw1a9Fs29r9Iqrn0kay5Cr13ZFWDJr12 gr4jkw13WFn8KwbCm3ZEXasCq-sJn29KB7ZKAUJUUUUf529EdanIXcx71UUUUU7KY7ZEXa sCq-sGcSsGvfJ3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU 0xBIdaVrnRJUUUBvb4IE77IF4wAFF20E14v26r1j6r4UM7CY07I20VC2zVCF04k26cxKx2 IYs7xG6rWj6s0DM7CIcVAFz4kK6r1Y6r17M28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48v e4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_Ar0_tr1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI 0_Cr0_Gr1UM28EF7xvwVC2z280aVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIEc7CjxVAF wI0_Gr1j6F4UJwAaw2AFwI0_JF0_Jw1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqjxCEc2 xF0cIa020Ex4CE44I27wAqx4xG64xvF2IEw4CE5I8CrVC2j2WlYx0E2Ix0cI8IcVAFwI0_ Wrv_ZF1lYx0Ex4A2jsIE14v26F4j6r4UJwAm72CE4IkC6x0Yz7v_Jr0_Gr1lF7xvr2IYc2 Ij64vIr41lc7CjxVAaw2AFwI0_JF0_Jw1l42xK82IYc2Ij64vIr41l4I8I3I0E4IkC6x0Y z7v_Jr0_Gr1l4IxYO2xFxVAFwI0_JF0_Jw1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s026x 8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r1q6r43MIIYrxkI7VAKI48JMIIF0xvE 2Ix0cI8IcVAFwI0_Ar0_tr1lIxAIcVC0I7IYx2IY6xkF7I0E14v26F4j6r4UJwCI42IY6x AIw20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Cr0_Gr1UMIIF0xvEx4A2jsIE c7CjxVAFwI0_Gr0_Gr1UYxBIdaVFxhVjvjDU0xZFpf9x07jxxhdUUUUU= X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net X-Patchwork-Delegate: kuba@kernel.org Add definitions for Loongson platform. Signed-off-by: Feiyang Chen --- .../net/ethernet/stmicro/stmmac/dwmac1000.h | 4 +- .../ethernet/stmicro/stmmac/dwmac1000_core.c | 43 +++++++--- .../ethernet/stmicro/stmmac/dwmac1000_dma.c | 10 ++- .../net/ethernet/stmicro/stmmac/dwmac_dma.h | 2 + .../net/ethernet/stmicro/stmmac/dwmac_lib.c | 84 +++++++++++++++++-- 5 files changed, 119 insertions(+), 24 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h index 4296ddda8aaa..f827bf8f30a9 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h @@ -76,9 +76,9 @@ enum power_event { #define LPI_CTRL_STATUS_TLPIEN 0x00000001 /* Transmit LPI Entry */ /* GMAC HW ADDR regs */ -#define GMAC_ADDR_HIGH(reg) ((reg > 15) ? 0x00000800 + (reg - 16) * 8 : \ +#define GMAC_ADDR_HIGH(reg, x) ((reg > 15) ? 0x00000800 + (reg - 16) * 8 * (x) : \ 0x00000040 + (reg * 8)) -#define GMAC_ADDR_LOW(reg) ((reg > 15) ? 0x00000804 + (reg - 16) * 8 : \ +#define GMAC_ADDR_LOW(reg, x) ((reg > 15) ? 0x00000804 + (reg - 16) * 8 * (x) : \ 0x00000044 + (reg * 8)) #define GMAC_MAX_PERFECT_ADDRESSES 1 diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c index a9b42a122ed6..1063865d126e 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c @@ -24,6 +24,7 @@ static void dwmac1000_core_init(struct mac_device_info *hw, struct net_device *dev) { + struct stmmac_priv *priv = netdev_priv(dev); void __iomem *ioaddr = hw->pcsr; u32 value = readl(ioaddr + GMAC_CONTROL); int mtu = dev->mtu; @@ -31,6 +32,9 @@ static void dwmac1000_core_init(struct mac_device_info *hw, /* Configure GMAC core */ value |= GMAC_CORE_INIT; + if (priv->plat->dwmac_is_loongson) + value |= GMAC_CONTROL_ACS; + if (mtu > 1500) value |= GMAC_CONTROL_2K; if (mtu > 2000) @@ -100,9 +104,10 @@ static void dwmac1000_set_umac_addr(struct stmmac_priv *priv, const unsigned char *addr, unsigned int reg_n) { + bool is_loongson = priv->plat->dwmac_is_loongson; void __iomem *ioaddr = hw->pcsr; - stmmac_set_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n), - GMAC_ADDR_LOW(reg_n)); + stmmac_set_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n, !is_loongson), + GMAC_ADDR_LOW(reg_n, !is_loongson)); } static void dwmac1000_get_umac_addr(struct stmmac_priv *priv, @@ -110,9 +115,10 @@ static void dwmac1000_get_umac_addr(struct stmmac_priv *priv, unsigned char *addr, unsigned int reg_n) { + bool is_loongson = priv->plat->dwmac_is_loongson; void __iomem *ioaddr = hw->pcsr; - stmmac_get_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n), - GMAC_ADDR_LOW(reg_n)); + stmmac_get_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n, !is_loongson), + GMAC_ADDR_LOW(reg_n, !is_loongson)); } static void dwmac1000_set_mchash(void __iomem *ioaddr, u32 *mcfilterbits, @@ -144,6 +150,7 @@ static void dwmac1000_set_filter(struct stmmac_priv *priv, struct mac_device_info *hw, struct net_device *dev) { + bool is_loongson = priv->plat->dwmac_is_loongson; void __iomem *ioaddr = (void __iomem *)dev->base_addr; unsigned int value = 0; unsigned int perfect_addr_number = hw->unicast_filter_entries; @@ -156,7 +163,9 @@ static void dwmac1000_set_filter(struct stmmac_priv *priv, memset(mc_filter, 0, sizeof(mc_filter)); if (dev->flags & IFF_PROMISC) { - value = GMAC_FRAME_FILTER_PR | GMAC_FRAME_FILTER_PCF; + value = GMAC_FRAME_FILTER_PR; + if (!is_loongson) + value |= GMAC_FRAME_FILTER_PCF; } else if (dev->flags & IFF_ALLMULTI) { value = GMAC_FRAME_FILTER_PM; /* pass all multi */ } else if (!netdev_mc_empty(dev) && (mcbitslog2 == 0)) { @@ -200,14 +209,14 @@ static void dwmac1000_set_filter(struct stmmac_priv *priv, netdev_for_each_uc_addr(ha, dev) { stmmac_set_mac_addr(ioaddr, ha->addr, - GMAC_ADDR_HIGH(reg), - GMAC_ADDR_LOW(reg)); + GMAC_ADDR_HIGH(reg, !is_loongson), + GMAC_ADDR_LOW(reg, !is_loongson)); reg++; } while (reg < perfect_addr_number) { - writel(0, ioaddr + GMAC_ADDR_HIGH(reg)); - writel(0, ioaddr + GMAC_ADDR_LOW(reg)); + writel(0, ioaddr + GMAC_ADDR_HIGH(reg, !is_loongson)); + writel(0, ioaddr + GMAC_ADDR_LOW(reg, !is_loongson)); reg++; } } @@ -562,8 +571,20 @@ int dwmac1000_setup(struct stmmac_priv *priv) { dev_info(priv->device, "\tDWMAC1000\n"); - priv->plat->dwmac_is_loongson = false; - priv->plat->dwmac_regs = &dwmac_default_dma_regs; + if (priv->plat->dma_cfg->dma64) + priv->plat->dwmac_regs = &dwmac_loongson64_dma_regs; + else + priv->plat->dwmac_regs = &dwmac_default_dma_regs; + + return _dwmac1000_setup(priv); +} + +int dwmac_loongson_setup(struct stmmac_priv *priv) +{ + dev_info(priv->device, "\tDWMAC1000(LOONGSON)\n"); + + priv->plat->dwmac_is_loongson = true; + priv->plat->dwmac_regs = &dwmac_loongson_dma_regs; return _dwmac1000_setup(priv); } diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c index 632c4f110d01..7aa450d6a81a 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c @@ -329,8 +329,14 @@ static int dwmac1000_get_hw_feature(struct stmmac_priv *priv, dma_cap->rx_coe_type2 = (hw_cap & DMA_HW_FEAT_RXTYP2COE) >> 18; dma_cap->rxfifo_over_2048 = (hw_cap & DMA_HW_FEAT_RXFIFOSIZE) >> 19; /* TX and RX number of channels */ - dma_cap->number_rx_channel = (hw_cap & DMA_HW_FEAT_RXCHCNT) >> 20; - dma_cap->number_tx_channel = (hw_cap & DMA_HW_FEAT_TXCHCNT) >> 22; + if (priv->plat->dwmac_is_loongson && + ((hw_cap & (DMA_HW_FEAT_RXCHCNT | DMA_HW_FEAT_TXCHCNT)) >> 20) == 0) { + dma_cap->number_rx_channel = 8; + dma_cap->number_tx_channel = 8; + } else { + dma_cap->number_rx_channel = (hw_cap & DMA_HW_FEAT_RXCHCNT) >> 20; + dma_cap->number_tx_channel = (hw_cap & DMA_HW_FEAT_TXCHCNT) >> 22; + } /* Alternate (enhanced) DESC mode */ dma_cap->enh_desc = (hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24; diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h index 915a4d70fd3b..3828902baa80 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h @@ -160,6 +160,8 @@ #define NUM_DWMAC4_DMA_REGS 27 extern const struct dwmac_regs dwmac_default_dma_regs; +extern const struct dwmac_regs dwmac_loongson_dma_regs; +extern const struct dwmac_regs dwmac_loongson64_dma_regs; void dwmac_enable_dma_transmission(struct stmmac_priv *priv, void __iomem *ioaddr, u32 chan); diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c index 99838497b183..7911eab175d9 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c @@ -20,6 +20,21 @@ static const struct dwmac_dma_addrs default_dma_addrs = { .cur_rx_buf_addr = 0x00001054 }; +static const struct dwmac_dma_addrs loongson_dma_addrs = { + .chan_offset = 0x100, + .rcv_base_addr = 0x0000100c, + .tx_base_addr = 0x00001010, + .cur_tx_buf_addr = 0x00001050, + .cur_rx_buf_addr = 0x00001054 +}; + +static const struct dwmac_dma_addrs loongson64_dma_addrs = { + .rcv_base_addr = 0x00001090, + .tx_base_addr = 0x00001098, + .cur_tx_buf_addr = 0x000010b0, + .cur_rx_buf_addr = 0x000010b8 +}; + static const struct dwmac_dma_axi default_dma_axi = { .wr_osr_lmt = GENMASK(23, 20), .wr_osr_lmt_shift = 20, @@ -30,11 +45,26 @@ static const struct dwmac_dma_axi default_dma_axi = { .osr_max = 0xf }; +static const struct dwmac_dma_axi loongson_dma_axi = { + .wr_osr_lmt = BIT(20), + .wr_osr_lmt_shift = 20, + .wr_osr_lmt_mask = 0x1, + .rd_osr_lmt = BIT(16), + .rd_osr_lmt_shift = 16, + .rd_osr_lmt_mask = 0x1, + .osr_max = 0x1 +}; + static const struct dwmac_dma_intr_ena default_dma_intr_ena = { .nie = 0x00010000, .aie = 0x00008000 }; +static const struct dwmac_dma_intr_ena loongson_dma_intr_ena = { + .nie = 0x00060000, + .aie = 0x00018000 +}; + static const struct dwmac_dma_status default_dma_status = { .glpii = 0x40000000, .eb_mask = 0x00380000, @@ -47,6 +77,18 @@ static const struct dwmac_dma_status default_dma_status = { .fbi = 0x00002000 }; +static const struct dwmac_dma_status loongson_dma_status = { + .glpii = 0x10000000, + .eb_mask = 0x0e000000, + .ts_mask = 0x01c00000, + .ts_shift = 22, + .rs_mask = 0x00380000, + .rs_shift = 19, + .nis = 0x00040000 | 0x00020000, + .ais = 0x00010000 | 0x00008000, + .fbi = 0x00002000 | 0x00001000 +}; + const struct dwmac_regs dwmac_default_dma_regs = { .addrs = &default_dma_addrs, .axi = &default_dma_axi, @@ -54,17 +96,37 @@ const struct dwmac_regs dwmac_default_dma_regs = { .status = &default_dma_status }; +const struct dwmac_regs dwmac_loongson_dma_regs = { + .addrs = &loongson_dma_addrs, + .axi = &loongson_dma_axi, + .intr_ena = &loongson_dma_intr_ena, + .status = &loongson_dma_status +}; + +const struct dwmac_regs dwmac_loongson64_dma_regs = { + .addrs = &loongson64_dma_addrs, + .axi = &loongson_dma_axi, + .intr_ena = &default_dma_intr_ena, + .status = &default_dma_status +}; + int dwmac_dma_reset(void __iomem *ioaddr) { + int err; + int cnt = 5; u32 value = readl(ioaddr + DMA_BUS_MODE); /* DMA SW reset */ - value |= DMA_BUS_MODE_SFT_RESET; - writel(value, ioaddr + DMA_BUS_MODE); + do { + value |= DMA_BUS_MODE_SFT_RESET; + writel(value, ioaddr + DMA_BUS_MODE); + + err = readl_poll_timeout(ioaddr + DMA_BUS_MODE, value, + !(value & DMA_BUS_MODE_SFT_RESET), + 10000, 200000); + } while (cnt-- && err); - return readl_poll_timeout(ioaddr + DMA_BUS_MODE, value, - !(value & DMA_BUS_MODE_SFT_RESET), - 10000, 200000); + return err; } /* CSR1 enables the transmit DMA to check for new descriptor */ @@ -267,12 +329,16 @@ int dwmac_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr, x->rx_early_irq++; } /* Optional hardware blocks, interrupts should be disabled */ - if (unlikely(intr_status & - (DMA_STATUS_GPI | DMA_STATUS_GMI | DMA_STATUS_GLI))) + if (!priv->plat->dwmac_is_loongson && + unlikely(intr_status & (DMA_STATUS_GPI | DMA_STATUS_GMI | DMA_STATUS_GLI))) pr_warn("%s: unexpected status %08x\n", __func__, intr_status); - /* Clear the interrupt by writing a logic 1 to the CSR5[15-0] */ - writel((intr_status & 0x1ffff), ioaddr + DMA_STATUS); + if (priv->plat->dwmac_is_loongson) + writel((intr_status & 0x7ffff), ioaddr + DMA_STATUS); + else { + /* Clear the interrupt by writing a logic 1 to the CSR5[15-0] */ + writel((intr_status & 0x1ffff), ioaddr + DMA_STATUS); + } return ret; } From patchwork Thu Jul 27 07:18:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Feiyang Chen X-Patchwork-Id: 13329050 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E7FEAC8C4 for ; Thu, 27 Jul 2023 07:18:26 +0000 (UTC) Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id BEBCA83D1 for ; Thu, 27 Jul 2023 00:18:14 -0700 (PDT) Received: from loongson.cn (unknown [112.20.109.108]) by gateway (Coremail) with SMTP id _____8Dx6eo1GsJkMJwKAA--.20857S3; Thu, 27 Jul 2023 15:18:13 +0800 (CST) Received: from localhost.localdomain (unknown [112.20.109.108]) by localhost.localdomain (Coremail) with SMTP id AQAAf8BxB80wGsJkNLc8AA--.24390S4; Thu, 27 Jul 2023 15:18:11 +0800 (CST) From: Feiyang Chen To: andrew@lunn.ch, hkallweit1@gmail.com, peppe.cavallaro@st.com, alexandre.torgue@foss.st.com, joabreu@synopsys.com, chenhuacai@loongson.cn Cc: Feiyang Chen , linux@armlinux.org.uk, dongbiao@loongson.cn, loongson-kernel@lists.loongnix.cn, netdev@vger.kernel.org, loongarch@lists.linux.dev, chris.chenfeiyang@gmail.com Subject: [PATCH v2 06/10] net: stmmac: Add Loongson HWIF entry Date: Thu, 27 Jul 2023 15:18:06 +0800 Message-Id: <7cae63ede2792cb2a7189f251b282aecbb0945b1.1690439335.git.chenfeiyang@loongson.cn> X-Mailer: git-send-email 2.39.3 In-Reply-To: References: Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-CM-TRANSID: AQAAf8BxB80wGsJkNLc8AA--.24390S4 X-CM-SenderInfo: hfkh0wphl1t03j6o00pqjv00gofq/ X-Coremail-Antispam: 1Uk129KBj93XoW3CF4UKw18GF4kuw4UKFW8KrX_yoWDWFW8pa yUAa4qvry8tF1Igan5Aw4DuFy5K34SkF42y3yfG3yagF4avr9Fqr9IqFWYyrnrGFW5Xa4a qFyq9w1ku3WUJrgCm3ZEXasCq-sJn29KB7ZKAUJUUUUf529EdanIXcx71UUUUU7KY7ZEXa sCq-sGcSsGvfJ3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU 0xBIdaVrnRJUUUBvb4IE77IF4wAFF20E14v26r1j6r4UM7CY07I20VC2zVCF04k26cxKx2 IYs7xG6rWj6s0DM7CIcVAFz4kK6r1Y6r17M28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48v e4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_Ar0_tr1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI 0_Cr0_Gr1UM28EF7xvwVC2z280aVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIEc7CjxVAF wI0_Gr1j6F4UJwAaw2AFwI0_JF0_Jw1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqjxCEc2 xF0cIa020Ex4CE44I27wAqx4xG64xvF2IEw4CE5I8CrVC2j2WlYx0E2Ix0cI8IcVAFwI0_ Wrv_ZF1lYx0Ex4A2jsIE14v26F4j6r4UJwAm72CE4IkC6x0Yz7v_Jr0_Gr1lF7xvr2IYc2 Ij64vIr41lc7CjxVAaw2AFwI0_JF0_Jw1l42xK82IYc2Ij64vIr41l4I8I3I0E4IkC6x0Y z7v_Jr0_Gr1l4IxYO2xFxVAFwI0_JF0_Jw1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s026x 8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r1q6r43MIIYrxkI7VAKI48JMIIF0xvE 2Ix0cI8IcVAFwI0_Ar0_tr1lIxAIcVC0I7IYx2IY6xkF7I0E14v26F4j6r4UJwCI42IY6x AIw20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Cr0_Gr1UMIIF0xvEx4A2jsIE c7CjxVAFwI0_Gr0_Gr1UYxBIdaVFxhVjvjDU0xZFpf9x07jxxhdUUUUU= X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net X-Patchwork-Delegate: kuba@kernel.org Add a new entry to HWIF table for Loongson. Signed-off-by: Feiyang Chen --- drivers/net/ethernet/stmicro/stmmac/common.h | 3 ++ .../ethernet/stmicro/stmmac/dwmac1000_dma.c | 6 +++ drivers/net/ethernet/stmicro/stmmac/hwif.c | 48 ++++++++++++++++++- .../net/ethernet/stmicro/stmmac/stmmac_main.c | 25 ++++++---- include/linux/stmmac.h | 1 + 5 files changed, 73 insertions(+), 10 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index 16e67c18b6f7..267f9a7913ac 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -29,11 +29,13 @@ /* Synopsys Core versions */ #define DWMAC_CORE_3_40 0x34 #define DWMAC_CORE_3_50 0x35 +#define DWMAC_CORE_3_70 0x37 #define DWMAC_CORE_4_00 0x40 #define DWMAC_CORE_4_10 0x41 #define DWMAC_CORE_5_00 0x50 #define DWMAC_CORE_5_10 0x51 #define DWMAC_CORE_5_20 0x52 +#define DWLGMAC_CORE_1_00 0x10 #define DWXGMAC_CORE_2_10 0x21 #define DWXLGMAC_CORE_2_00 0x20 @@ -547,6 +549,7 @@ int dwmac1000_setup(struct stmmac_priv *priv); int dwmac4_setup(struct stmmac_priv *priv); int dwxgmac2_setup(struct stmmac_priv *priv); int dwxlgmac2_setup(struct stmmac_priv *priv); +int dwmac_loongson_setup(struct stmmac_priv *priv); void stmmac_set_mac_addr(void __iomem *ioaddr, const u8 addr[6], unsigned int high, unsigned int low); diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c index 7aa450d6a81a..5da5f111d7e0 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c @@ -172,6 +172,12 @@ static void dwmac1000_dma_init_rx(struct stmmac_priv *priv, chan * DMA_CHAN_OFFSET); writel(upper_32_bits(dma_rx_phy), ioaddr + DMA_RCV_BASE_ADDR_HI + chan * DMA_CHAN_OFFSET); + if (priv->plat->has_lgmac) { + writel(upper_32_bits(dma_rx_phy), + ioaddr + DMA_RCV_BASE_ADDR_SHADOW1); + writel(upper_32_bits(dma_rx_phy), + ioaddr + DMA_RCV_BASE_ADDR_SHADOW2); + } } else { /* RX descriptor base address list must be written into DMA CSR3 */ writel(lower_32_bits(dma_rx_phy), ioaddr + DMA_RCV_BASE_ADDR + diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.c b/drivers/net/ethernet/stmicro/stmmac/hwif.c index b8ba8f2d8041..b376ac4f80d5 100644 --- a/drivers/net/ethernet/stmicro/stmmac/hwif.c +++ b/drivers/net/ethernet/stmicro/stmmac/hwif.c @@ -58,7 +58,8 @@ static int stmmac_dwmac1_quirks(struct stmmac_priv *priv) dev_info(priv->device, "Enhanced/Alternate descriptors\n"); /* GMAC older than 3.50 has no extended descriptors */ - if (priv->synopsys_id >= DWMAC_CORE_3_50) { + if (priv->synopsys_id >= DWMAC_CORE_3_50 || + priv->plat->has_lgmac) { dev_info(priv->device, "Enabled extended descriptors\n"); priv->extend_desc = 1; } else { @@ -104,6 +105,7 @@ static const struct stmmac_hwif_entry { bool gmac; bool gmac4; bool xgmac; + bool lgmac; u32 min_id; u32 dev_id; const struct stmmac_regs_off regs; @@ -122,6 +124,7 @@ static const struct stmmac_hwif_entry { .gmac = false, .gmac4 = false, .xgmac = false, + .lgmac = false, .min_id = 0, .regs = { .ptp_off = PTP_GMAC3_X_OFFSET, @@ -140,6 +143,7 @@ static const struct stmmac_hwif_entry { .gmac = true, .gmac4 = false, .xgmac = false, + .lgmac = false, .min_id = 0, .regs = { .ptp_off = PTP_GMAC3_X_OFFSET, @@ -158,6 +162,7 @@ static const struct stmmac_hwif_entry { .gmac = false, .gmac4 = true, .xgmac = false, + .lgmac = false, .min_id = 0, .regs = { .ptp_off = PTP_GMAC4_OFFSET, @@ -176,6 +181,7 @@ static const struct stmmac_hwif_entry { .gmac = false, .gmac4 = true, .xgmac = false, + .lgmac = false, .min_id = DWMAC_CORE_4_00, .regs = { .ptp_off = PTP_GMAC4_OFFSET, @@ -194,6 +200,7 @@ static const struct stmmac_hwif_entry { .gmac = false, .gmac4 = true, .xgmac = false, + .lgmac = false, .min_id = DWMAC_CORE_4_10, .regs = { .ptp_off = PTP_GMAC4_OFFSET, @@ -212,6 +219,7 @@ static const struct stmmac_hwif_entry { .gmac = false, .gmac4 = true, .xgmac = false, + .lgmac = false, .min_id = DWMAC_CORE_5_10, .regs = { .ptp_off = PTP_GMAC4_OFFSET, @@ -230,6 +238,7 @@ static const struct stmmac_hwif_entry { .gmac = false, .gmac4 = false, .xgmac = true, + .lgmac = false, .min_id = DWXGMAC_CORE_2_10, .dev_id = DWXGMAC_ID, .regs = { @@ -249,6 +258,7 @@ static const struct stmmac_hwif_entry { .gmac = false, .gmac4 = false, .xgmac = true, + .lgmac = false, .min_id = DWXLGMAC_CORE_2_00, .dev_id = DWXLGMAC_ID, .regs = { @@ -264,6 +274,42 @@ static const struct stmmac_hwif_entry { .mmc = &dwxgmac_mmc_ops, .setup = dwxlgmac2_setup, .quirks = stmmac_dwxlgmac_quirks, + }, { + .gmac = true, + .gmac4 = false, + .xgmac = false, + .lgmac = true, + .min_id = DWLGMAC_CORE_1_00, + .regs = { + .ptp_off = PTP_GMAC3_X_OFFSET, + .mmc_off = MMC_GMAC3_X_OFFSET, + }, + .desc = NULL, + .dma = &dwmac1000_dma_ops, + .mac = &dwmac1000_ops, + .hwtimestamp = &stmmac_ptp, + .mode = NULL, + .tc = NULL, + .setup = dwmac_loongson_setup, + .quirks = stmmac_dwmac1_quirks, + }, { + .gmac = true, + .gmac4 = false, + .xgmac = false, + .lgmac = true, + .min_id = DWMAC_CORE_3_50, + .regs = { + .ptp_off = PTP_GMAC3_X_OFFSET, + .mmc_off = MMC_GMAC3_X_OFFSET, + }, + .desc = NULL, + .dma = &dwmac1000_dma_ops, + .mac = &dwmac1000_ops, + .hwtimestamp = &stmmac_ptp, + .mode = NULL, + .tc = NULL, + .setup = dwmac1000_setup, + .quirks = stmmac_dwmac1_quirks, }, }; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index e8619853b6d6..829de274e75d 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -3505,17 +3505,21 @@ static int stmmac_request_irq_multi_msi(struct net_device *dev) { struct stmmac_priv *priv = netdev_priv(dev); enum request_irq_err irq_err; + unsigned long flags = 0; cpumask_t cpu_mask; int irq_idx = 0; char *int_name; int ret; int i; + if (priv->plat->has_lgmac) + flags |= IRQF_TRIGGER_RISING; + /* For common interrupt */ int_name = priv->int_name_mac; sprintf(int_name, "%s:%s", dev->name, "mac"); ret = request_irq(dev->irq, stmmac_mac_interrupt, - 0, int_name, dev); + flags, int_name, dev); if (unlikely(ret < 0)) { netdev_err(priv->dev, "%s: alloc mac MSI %d (error: %d)\n", @@ -3532,7 +3536,7 @@ static int stmmac_request_irq_multi_msi(struct net_device *dev) sprintf(int_name, "%s:%s", dev->name, "wol"); ret = request_irq(priv->wol_irq, stmmac_mac_interrupt, - 0, int_name, dev); + flags, int_name, dev); if (unlikely(ret < 0)) { netdev_err(priv->dev, "%s: alloc wol MSI %d (error: %d)\n", @@ -3550,7 +3554,7 @@ static int stmmac_request_irq_multi_msi(struct net_device *dev) sprintf(int_name, "%s:%s", dev->name, "lpi"); ret = request_irq(priv->lpi_irq, stmmac_mac_interrupt, - 0, int_name, dev); + flags, int_name, dev); if (unlikely(ret < 0)) { netdev_err(priv->dev, "%s: alloc lpi MSI %d (error: %d)\n", @@ -3568,7 +3572,7 @@ static int stmmac_request_irq_multi_msi(struct net_device *dev) sprintf(int_name, "%s:%s", dev->name, "safety-ce"); ret = request_irq(priv->sfty_ce_irq, stmmac_safety_interrupt, - 0, int_name, dev); + flags, int_name, dev); if (unlikely(ret < 0)) { netdev_err(priv->dev, "%s: alloc sfty ce MSI %d (error: %d)\n", @@ -3586,7 +3590,7 @@ static int stmmac_request_irq_multi_msi(struct net_device *dev) sprintf(int_name, "%s:%s", dev->name, "safety-ue"); ret = request_irq(priv->sfty_ue_irq, stmmac_safety_interrupt, - 0, int_name, dev); + flags, int_name, dev); if (unlikely(ret < 0)) { netdev_err(priv->dev, "%s: alloc sfty ue MSI %d (error: %d)\n", @@ -3607,7 +3611,7 @@ static int stmmac_request_irq_multi_msi(struct net_device *dev) sprintf(int_name, "%s:%s-%d", dev->name, "rx", i); ret = request_irq(priv->rx_irq[i], stmmac_msi_intr_rx, - 0, int_name, &priv->dma_conf.rx_queue[i]); + flags, int_name, &priv->dma_conf.rx_queue[i]); if (unlikely(ret < 0)) { netdev_err(priv->dev, "%s: alloc rx-%d MSI %d (error: %d)\n", @@ -3632,7 +3636,7 @@ static int stmmac_request_irq_multi_msi(struct net_device *dev) sprintf(int_name, "%s:%s-%d", dev->name, "tx", i); ret = request_irq(priv->tx_irq[i], stmmac_msi_intr_tx, - 0, int_name, &priv->dma_conf.tx_queue[i]); + flags, int_name, &priv->dma_conf.tx_queue[i]); if (unlikely(ret < 0)) { netdev_err(priv->dev, "%s: alloc tx-%d MSI %d (error: %d)\n", @@ -6057,8 +6061,10 @@ static u16 stmmac_select_queue(struct net_device *dev, struct sk_buff *skb, struct net_device *sb_dev) { int gso = skb_shinfo(skb)->gso_type; + struct stmmac_priv *priv = netdev_priv(dev); - if (gso & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6 | SKB_GSO_UDP_L4)) { + if ((gso & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6 | SKB_GSO_UDP_L4)) || + priv->plat->has_lgmac) { /* * There is no way to determine the number of TSO/USO * capable Queues. Let's use always the Queue 0 @@ -6936,7 +6942,8 @@ static int stmmac_hw_init(struct stmmac_priv *priv) * riwt_off field from the platform. */ if (((priv->synopsys_id >= DWMAC_CORE_3_50) || - (priv->plat->has_xgmac)) && (!priv->plat->riwt_off)) { + (priv->plat->has_xgmac) || (priv->plat->has_lgmac)) && + (!priv->plat->riwt_off)) { priv->use_riwt = 1; dev_info(priv->device, "Enable RX Mitigation via HW Watchdog Timer\n"); diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h index 46bccc34814d..e21076f57205 100644 --- a/include/linux/stmmac.h +++ b/include/linux/stmmac.h @@ -344,5 +344,6 @@ struct plat_stmmacenet_data { bool has_integrated_pcs; const struct dwmac_regs *dwmac_regs; bool dwmac_is_loongson; + int has_lgmac; }; #endif From patchwork Thu Jul 27 07:18:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Feiyang Chen X-Patchwork-Id: 13329051 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 192ECC8C4 for ; Thu, 27 Jul 2023 07:18:28 +0000 (UTC) Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id D7E4B83D7 for ; Thu, 27 Jul 2023 00:18:15 -0700 (PDT) Received: from loongson.cn (unknown [112.20.109.108]) by gateway (Coremail) with SMTP id _____8BxXes2GsJkOZwKAA--.21095S3; Thu, 27 Jul 2023 15:18:14 +0800 (CST) Received: from localhost.localdomain (unknown [112.20.109.108]) by localhost.localdomain (Coremail) with SMTP id AQAAf8BxB80wGsJkNLc8AA--.24390S5; Thu, 27 Jul 2023 15:18:13 +0800 (CST) From: Feiyang Chen To: andrew@lunn.ch, hkallweit1@gmail.com, peppe.cavallaro@st.com, alexandre.torgue@foss.st.com, joabreu@synopsys.com, chenhuacai@loongson.cn Cc: Feiyang Chen , linux@armlinux.org.uk, dongbiao@loongson.cn, loongson-kernel@lists.loongnix.cn, netdev@vger.kernel.org, loongarch@lists.linux.dev, chris.chenfeiyang@gmail.com Subject: [PATCH v2 07/10] net: stmmac: dwmac-loongson: Add LS7A support Date: Thu, 27 Jul 2023 15:18:07 +0800 Message-Id: X-Mailer: git-send-email 2.39.3 In-Reply-To: References: Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-CM-TRANSID: AQAAf8BxB80wGsJkNLc8AA--.24390S5 X-CM-SenderInfo: hfkh0wphl1t03j6o00pqjv00gofq/ X-Coremail-Antispam: 1Uk129KBj93XoW3Jry7Aw1fAr17GFWkJr48Zrc_yoWxZr1xpa yfCasxKrWftr1Igan5ZFWDZF1YkrW29348K3y2k3s7uas0yr4YqF1ftrWjyF97AFZ5uw17 Wr1jgF48WF4DZFbCm3ZEXasCq-sJn29KB7ZKAUJUUUUf529EdanIXcx71UUUUU7KY7ZEXa sCq-sGcSsGvfJ3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU 0xBIdaVrnRJUUUBmb4IE77IF4wAFF20E14v26r1j6r4UM7CY07I20VC2zVCF04k26cxKx2 IYs7xG6rWj6s0DM7CIcVAFz4kK6r1Y6r17M28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48v e4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_Ar0_tr1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI 0_Cr0_Gr1UM28EF7xvwVC2z280aVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIEc7CjxVAF wI0_Gr1j6F4UJwAaw2AFwI0_JF0_Jw1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqjxCEc2 xF0cIa020Ex4CE44I27wAqx4xG64xvF2IEw4CE5I8CrVC2j2WlYx0E2Ix0cI8IcVAFwI0_ ZF0_GryDMcIj6I8E87Iv67AKxVWxJVW8Jr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0Y48Icx kI7VAKI48JMxkF7I0En4kS14v26r126r1DMxAIw28IcxkI7VAKI48JMxC20s026xCaFVCj c4AY6r1j6r4UMxCIbckI1I0E14v26r126r1DMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxV Cjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVWUtVW8ZwCIc40Y0x0EwIxGrwCI42IY 6xIIjxv20xvE14v26F1j6w1UMIIF0xvE2Ix0cI8IcVCY1x0267AKxVWxJVW8Jr1lIxAIcV CF04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26F4j6r4UJwCI42IY6I8E87Iv 6xkF7I0E14v26r4j6r4UJbIYCTnIWIevJa73UjIFyTuYvjxUxNeODUUUU X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net X-Patchwork-Delegate: kuba@kernel.org Current dwmac-loongson only support LS2K in the "probed with PCI and configured with DT" manner. Add LS7A support on which the devices are fully PCI (non-DT). Signed-off-by: Huacai Chen Signed-off-by: Feiyang Chen --- .../ethernet/stmicro/stmmac/dwmac-loongson.c | 149 ++++++++++-------- 1 file changed, 85 insertions(+), 64 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c index a25c187d3185..3ab55340a6b8 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c @@ -9,14 +9,21 @@ #include #include "stmmac.h" -static int loongson_default_data(struct plat_stmmacenet_data *plat) +struct stmmac_pci_info { + int (*setup)(struct pci_dev *pdev, struct plat_stmmacenet_data *plat); +}; + +static void common_default_data(struct pci_dev *pdev, + struct plat_stmmacenet_data *plat) { + plat->bus_id = (pci_domain_nr(pdev->bus) << 16) | PCI_DEVID(pdev->bus->number, pdev->devfn); + plat->clk_csr = 2; /* clk_csr_i = 20-35MHz & MDC = clk_csr_i/16 */ plat->has_gmac = 1; plat->force_sf_dma_mode = 1; /* Set default value for multicast hash bins */ - plat->multicast_filter_bins = HASH_TABLE_SIZE; + plat->multicast_filter_bins = 256; /* Set default value for unicast filter entries */ plat->unicast_filter_entries = 1; @@ -35,59 +42,61 @@ static int loongson_default_data(struct plat_stmmacenet_data *plat) /* Disable RX queues routing by default */ plat->rx_queues_cfg[0].pkt_route = 0x0; - /* Default to phy auto-detection */ - plat->phy_addr = -1; - plat->dma_cfg->pbl = 32; plat->dma_cfg->pblx8 = true; - plat->multicast_filter_bins = 256; + plat->clk_ref_rate = 125000000; + plat->clk_ptp_rate = 125000000; + + plat->has_lgmac = 1; +} + +static int loongson_gmac_data(struct pci_dev *pdev, + struct plat_stmmacenet_data *plat) +{ + common_default_data(pdev, plat); + + plat->mdio_bus_data->phy_mask = 0; + + plat->phy_addr = -1; + plat->phy_interface = PHY_INTERFACE_MODE_RGMII_ID; + return 0; } -static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id *id) +static struct stmmac_pci_info loongson_gmac_pci_info = { + .setup = loongson_gmac_data, +}; + +static int loongson_dwmac_probe(struct pci_dev *pdev, + const struct pci_device_id *id) { + int ret, i, bus_id, phy_mode; struct plat_stmmacenet_data *plat; + struct stmmac_pci_info *info; struct stmmac_resources res; struct device_node *np; - int ret, i, phy_mode; - - np = dev_of_node(&pdev->dev); - - if (!np) { - pr_info("dwmac_loongson_pci: No OF node\n"); - return -ENODEV; - } - - if (!of_device_is_compatible(np, "loongson, pci-gmac")) { - pr_info("dwmac_loongson_pci: Incompatible OF node\n"); - return -ENODEV; - } plat = devm_kzalloc(&pdev->dev, sizeof(*plat), GFP_KERNEL); if (!plat) return -ENOMEM; + plat->mdio_bus_data = devm_kzalloc(&pdev->dev, + sizeof(*plat->mdio_bus_data), GFP_KERNEL); + if (!plat->mdio_bus_data) + return -ENOMEM; + + plat->dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*plat->dma_cfg), GFP_KERNEL); + if (!plat->dma_cfg) + return -ENOMEM; + + np = dev_of_node(&pdev->dev); plat->mdio_node = of_get_child_by_name(np, "mdio"); if (plat->mdio_node) { dev_info(&pdev->dev, "Found MDIO subnode\n"); - - plat->mdio_bus_data = devm_kzalloc(&pdev->dev, - sizeof(*plat->mdio_bus_data), - GFP_KERNEL); - if (!plat->mdio_bus_data) { - ret = -ENOMEM; - goto err_put_node; - } plat->mdio_bus_data->needs_reset = true; } - plat->dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*plat->dma_cfg), GFP_KERNEL); - if (!plat->dma_cfg) { - ret = -ENOMEM; - goto err_put_node; - } - /* Enable pci device */ ret = pci_enable_device(pdev); if (ret) { @@ -105,45 +114,55 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id break; } - plat->bus_id = of_alias_get_id(np, "ethernet"); - if (plat->bus_id < 0) - plat->bus_id = pci_dev_id(pdev); + pci_set_master(pdev); - phy_mode = device_get_phy_mode(&pdev->dev); - if (phy_mode < 0) { - dev_err(&pdev->dev, "phy_mode not found\n"); - ret = phy_mode; + info = (struct stmmac_pci_info *)id->driver_data; + ret = info->setup(pdev, plat); + if (ret) goto err_disable_device; - } - plat->phy_interface = phy_mode; - plat->interface = PHY_INTERFACE_MODE_GMII; + if (np) { + bus_id = of_alias_get_id(np, "ethernet"); + if (bus_id >= 0) + plat->bus_id = bus_id; - pci_set_master(pdev); + phy_mode = device_get_phy_mode(&pdev->dev); + if (phy_mode < 0) { + dev_err(&pdev->dev, "phy_mode not found\n"); + ret = phy_mode; + goto err_disable_device; + } + plat->phy_interface = phy_mode; + } - loongson_default_data(plat); pci_enable_msi(pdev); + memset(&res, 0, sizeof(res)); res.addr = pcim_iomap_table(pdev)[0]; + if (np) { + res.irq = of_irq_get_byname(np, "macirq"); + if (res.irq < 0) { + dev_err(&pdev->dev, "IRQ macirq not found\n"); + ret = -ENODEV; + goto err_disable_msi; + } - res.irq = of_irq_get_byname(np, "macirq"); - if (res.irq < 0) { - dev_err(&pdev->dev, "IRQ macirq not found\n"); - ret = -ENODEV; - goto err_disable_msi; - } - - res.wol_irq = of_irq_get_byname(np, "eth_wake_irq"); - if (res.wol_irq < 0) { - dev_info(&pdev->dev, "IRQ eth_wake_irq not found, using macirq\n"); - res.wol_irq = res.irq; - } + res.wol_irq = of_irq_get_byname(np, "eth_wake_irq"); + if (res.wol_irq < 0) { + dev_info(&pdev->dev, + "IRQ eth_wake_irq not found, using macirq\n"); + res.wol_irq = res.irq; + } - res.lpi_irq = of_irq_get_byname(np, "eth_lpi"); - if (res.lpi_irq < 0) { - dev_err(&pdev->dev, "IRQ eth_lpi not found\n"); - ret = -ENODEV; - goto err_disable_msi; + res.lpi_irq = of_irq_get_byname(np, "eth_lpi"); + if (res.lpi_irq < 0) { + dev_err(&pdev->dev, "IRQ eth_lpi not found\n"); + ret = -ENODEV; + goto err_disable_msi; + } + } else { + res.irq = pdev->irq; + res.wol_irq = pdev->irq; } ret = stmmac_dvr_probe(&pdev->dev, plat, &res); @@ -219,8 +238,10 @@ static int __maybe_unused loongson_dwmac_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(loongson_dwmac_pm_ops, loongson_dwmac_suspend, loongson_dwmac_resume); +#define PCI_DEVICE_ID_LOONGSON_GMAC 0x7a03 + static const struct pci_device_id loongson_dwmac_id_table[] = { - { PCI_VDEVICE(LOONGSON, 0x7a03) }, + { PCI_DEVICE_DATA(LOONGSON, GMAC, &loongson_gmac_pci_info) }, {} }; MODULE_DEVICE_TABLE(pci, loongson_dwmac_id_table); From patchwork Thu Jul 27 07:18:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Feiyang Chen X-Patchwork-Id: 13329053 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D5619C2DA for ; Thu, 27 Jul 2023 07:18:59 +0000 (UTC) Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 2865B271C for ; Thu, 27 Jul 2023 00:18:57 -0700 (PDT) Received: from loongson.cn (unknown [112.20.109.108]) by gateway (Coremail) with SMTP id _____8CxtPBfGsJkd5wKAA--.26951S3; Thu, 27 Jul 2023 15:18:55 +0800 (CST) Received: from localhost.localdomain (unknown [112.20.109.108]) by localhost.localdomain (Coremail) with SMTP id AQAAf8Ax8uReGsJkn7c8AA--.31333S2; Thu, 27 Jul 2023 15:18:54 +0800 (CST) From: Feiyang Chen To: andrew@lunn.ch, hkallweit1@gmail.com, peppe.cavallaro@st.com, alexandre.torgue@foss.st.com, joabreu@synopsys.com, chenhuacai@loongson.cn Cc: Feiyang Chen , linux@armlinux.org.uk, dongbiao@loongson.cn, loongson-kernel@lists.loongnix.cn, netdev@vger.kernel.org, loongarch@lists.linux.dev, chris.chenfeiyang@gmail.com Subject: [PATCH v2 08/10] net: stmmac: dwmac-loongson: Disable flow control for GMAC Date: Thu, 27 Jul 2023 15:18:51 +0800 Message-Id: <0ec0ae938964697010b3d035b7885e4dda89b012.1690439335.git.chenfeiyang@loongson.cn> X-Mailer: git-send-email 2.39.3 In-Reply-To: References: Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-CM-TRANSID: AQAAf8Ax8uReGsJkn7c8AA--.31333S2 X-CM-SenderInfo: hfkh0wphl1t03j6o00pqjv00gofq/ X-Coremail-Antispam: 1Uk129KBj93XoW7ZFyrWrWDCFy3Ww13KF15Awc_yoW8CF4Upa 9rAa4I9r97Jr47A3Z8Aw4DZFy5XayUKrZrWayxKw4fWFZ2kr9FqryYqayYvFy7ArW5XFya gr4jkr4UCF1DGrgCm3ZEXasCq-sJn29KB7ZKAUJUUUUf529EdanIXcx71UUUUU7KY7ZEXa sCq-sGcSsGvfJ3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU 0xBIdaVrnRJUUUBlb4IE77IF4wAFF20E14v26r1j6r4UM7CY07I20VC2zVCF04k26cxKx2 IYs7xG6rWj6s0DM7CIcVAFz4kK6r1Y6r17M28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48v e4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI 0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIE14v26r4UJVWxJr1l84ACjcxK6I8E87Iv6xkF7I0E 14v26r4UJVWxJr1ln4kS14v26r126r1DM2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6x kI12xvs2x26I8E6xACxx1l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6xIIjxv20xvE14v2 6Fy26r45twAv7VC2z280aVAFwI0_Cr0_Gr1UMcvjeVCFs4IE7xkEbVWUJVW8JwACjcxG0x vY0x0EwIxGrwCY1x0262kKe7AKxVWUAVWUtwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE 7xkEbVWUJVW8JwCFI7km07C267AKxVWUAVWUtwC20s026c02F40E14v26r1j6r18MI8I3I 0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAI cVC0I7IYx2IY67AKxVW7JVWDJwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Cr0_Gr1UMIIF0x vE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVWxJVW8Jr1lIxAIcVC2z280 aVCY1x0267AKxVW8JVW8JrUvcSsGvfC2KfnxnUUI43ZEXa7IU0wqXPUUUUU== X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net X-Patchwork-Delegate: kuba@kernel.org Loongson GMAC does not support Flow Control featurei. Use disable_flow_control flag to disable it. Signed-off-by: Feiyang Chen --- drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c | 2 ++ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 5 +++++ include/linux/stmmac.h | 1 + 3 files changed, 8 insertions(+) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c index 3ab55340a6b8..439a5f8bcabe 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c @@ -61,6 +61,8 @@ static int loongson_gmac_data(struct pci_dev *pdev, plat->phy_addr = -1; plat->phy_interface = PHY_INTERFACE_MODE_RGMII_ID; + plat->disable_flow_control = true; + return 0; } diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 829de274e75d..4f69cad0be42 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -3829,6 +3829,11 @@ static int __stmmac_open(struct net_device *dev, __func__, ret); goto init_phy_error; } + + if (priv->plat->disable_flow_control) { + phy_support_sym_pause(dev->phydev); + phy_set_sym_pause(dev->phydev, false, false, true); + } } /* Extra statistics */ diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h index e21076f57205..54b9f308aabb 100644 --- a/include/linux/stmmac.h +++ b/include/linux/stmmac.h @@ -345,5 +345,6 @@ struct plat_stmmacenet_data { const struct dwmac_regs *dwmac_regs; bool dwmac_is_loongson; int has_lgmac; + bool disable_flow_control; }; #endif From patchwork Thu Jul 27 07:18:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Feiyang Chen X-Patchwork-Id: 13329052 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 92210C13C for ; Thu, 27 Jul 2023 07:18:59 +0000 (UTC) Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 9A3012698 for ; Thu, 27 Jul 2023 00:18:57 -0700 (PDT) Received: from loongson.cn (unknown [112.20.109.108]) by gateway (Coremail) with SMTP id _____8BxpPBgGsJkgJwKAA--.26471S3; Thu, 27 Jul 2023 15:18:56 +0800 (CST) Received: from localhost.localdomain (unknown [112.20.109.108]) by localhost.localdomain (Coremail) with SMTP id AQAAf8Ax8uReGsJkn7c8AA--.31333S3; Thu, 27 Jul 2023 15:18:55 +0800 (CST) From: Feiyang Chen To: andrew@lunn.ch, hkallweit1@gmail.com, peppe.cavallaro@st.com, alexandre.torgue@foss.st.com, joabreu@synopsys.com, chenhuacai@loongson.cn Cc: Feiyang Chen , linux@armlinux.org.uk, dongbiao@loongson.cn, loongson-kernel@lists.loongnix.cn, netdev@vger.kernel.org, loongarch@lists.linux.dev, chris.chenfeiyang@gmail.com Subject: [PATCH v2 09/10] net: stmmac: dwmac-loongson: Add 64-bit DMA and multi-vector support Date: Thu, 27 Jul 2023 15:18:52 +0800 Message-Id: X-Mailer: git-send-email 2.39.3 In-Reply-To: References: Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-CM-TRANSID: AQAAf8Ax8uReGsJkn7c8AA--.31333S3 X-CM-SenderInfo: hfkh0wphl1t03j6o00pqjv00gofq/ X-Coremail-Antispam: 1Uk129KBj93XoWxWr1UWryrKryUXw4rAFW7WrX_yoW5WFWkp3 y3Aa47KrW8Xr17XanxJw4DAF15JrWav3y8Wr4akw1S9rZ0yryvqFyvgFWxXryxCrWkAF17 ZF4qyF48u3WDJ3XCm3ZEXasCq-sJn29KB7ZKAUJUUUUf529EdanIXcx71UUUUU7KY7ZEXa sCq-sGcSsGvfJ3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU 0xBIdaVrnRJUUUBlb4IE77IF4wAFF20E14v26r1j6r4UM7CY07I20VC2zVCF04k26cxKx2 IYs7xG6rWj6s0DM7CIcVAFz4kK6r1Y6r17M28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48v e4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI 0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIE14v26r4UJVWxJr1l84ACjcxK6I8E87Iv6xkF7I0E 14v26r4UJVWxJr1ln4kS14v26r126r1DM2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6x kI12xvs2x26I8E6xACxx1l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6xIIjxv20xvE14v2 6Fy26r45twAv7VC2z280aVAFwI0_Cr0_Gr1UMcvjeVCFs4IE7xkEbVWUJVW8JwACjcxG0x vY0x0EwIxGrwCY1x0262kKe7AKxVWUAVWUtwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE 7xkEbVWUJVW8JwCFI7km07C267AKxVWUAVWUtwC20s026c02F40E14v26r1j6r18MI8I3I 0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAI cVC0I7IYx2IY67AKxVWDJVCq3wCI42IY6xIIjxv20xvEc7CjxVAFwI0_Cr0_Gr1UMIIF0x vE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVWxJVW8Jr1lIxAIcVC2z280 aVCY1x0267AKxVW8JVW8JrUvcSsGvfC2KfnxnUUI43ZEXa7IU0wqXPUUUUU== X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net X-Patchwork-Delegate: kuba@kernel.org Set 64-Bit DMA for specific versions. Request allocation for multi- vector interrupts for DWLGMAC_CORE_1_00. If it fails, fallback to request allocation for single interrupts. Signed-off-by: Feiyang Chen --- .../ethernet/stmicro/stmmac/dwmac-loongson.c | 54 ++++++++++++++++++- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c index 439a5f8bcabe..2d6567f0da23 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c @@ -73,11 +73,12 @@ static struct stmmac_pci_info loongson_gmac_pci_info = { static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id *id) { - int ret, i, bus_id, phy_mode; + int ret, i, bus_id, phy_mode, ch_cnt, vecs; struct plat_stmmacenet_data *plat; struct stmmac_pci_info *info; struct stmmac_resources res; struct device_node *np; + u32 version; plat = devm_kzalloc(&pdev->dev, sizeof(*plat), GFP_KERNEL); if (!plat) @@ -167,12 +168,60 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, res.wol_irq = pdev->irq; } + version = readl(res.addr + GMAC_VERSION); + switch (version & 0xff) { + case DWLGMAC_CORE_1_00: + ch_cnt = 8; + plat->multi_msi_en = 1; + break; + case DWMAC_CORE_3_50: + fallthrough; + case DWMAC_CORE_3_70: + plat->multi_msi_en = 0; + if (version & 0x00008000) { + plat->host_dma_width = 64; + plat->dma_cfg->dma64 = true; + } + break; + default: + break; + } + + if (plat->multi_msi_en) { + plat->rx_queues_to_use = ch_cnt; + plat->tx_queues_to_use = ch_cnt; + + pci_disable_msi(pdev); + + res.irq = pci_irq_vector(pdev, 0); + res.wol_irq = res.irq; + vecs = roundup_pow_of_two(ch_cnt * 2 + 1); + if (pci_alloc_irq_vectors(pdev, vecs, vecs, PCI_IRQ_MSI) < 0) { + dev_info(&pdev->dev, + "MSI enable failed, Fallback to line interrupt\n"); + plat->multi_msi_en = 0; + } else { + /* + * INT NAME | MAC | CH7 rx | CH7 tx | ... | CH0 rx | CH0 tx | + * --------- ----- -------- -------- ... -------- -------- + * IRQ NUM | 0 | 1 | 2 | ... | 15 | 16 | + */ + for (i = 0; i < ch_cnt; i++) { + res.rx_irq[ch_cnt - 1 - i] = pci_irq_vector(pdev, 1 + i * 2); + res.tx_irq[ch_cnt - 1 - i] = pci_irq_vector(pdev, 2 + i * 2); + } + } + } + ret = stmmac_dvr_probe(&pdev->dev, plat, &res); if (ret) - goto err_disable_msi; + goto err_free_irq_vectors; return ret; +err_free_irq_vectors: + if (plat->multi_msi_en) + pci_free_irq_vectors(pdev); err_disable_msi: pci_disable_msi(pdev); err_disable_device: @@ -198,6 +247,7 @@ static void loongson_dwmac_remove(struct pci_dev *pdev) break; } + pci_free_irq_vectors(pdev); pci_disable_msi(pdev); pci_disable_device(pdev); } From patchwork Thu Jul 27 07:18:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Feiyang Chen X-Patchwork-Id: 13329054 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 383CCC14D for ; Thu, 27 Jul 2023 07:19:01 +0000 (UTC) Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 096802726 for ; Thu, 27 Jul 2023 00:18:58 -0700 (PDT) Received: from loongson.cn (unknown [112.20.109.108]) by gateway (Coremail) with SMTP id _____8CxtPBhGsJkipwKAA--.26952S3; Thu, 27 Jul 2023 15:18:57 +0800 (CST) Received: from localhost.localdomain (unknown [112.20.109.108]) by localhost.localdomain (Coremail) with SMTP id AQAAf8Ax8uReGsJkn7c8AA--.31333S4; Thu, 27 Jul 2023 15:18:56 +0800 (CST) From: Feiyang Chen To: andrew@lunn.ch, hkallweit1@gmail.com, peppe.cavallaro@st.com, alexandre.torgue@foss.st.com, joabreu@synopsys.com, chenhuacai@loongson.cn Cc: Feiyang Chen , linux@armlinux.org.uk, dongbiao@loongson.cn, loongson-kernel@lists.loongnix.cn, netdev@vger.kernel.org, loongarch@lists.linux.dev, chris.chenfeiyang@gmail.com Subject: [PATCH v2 10/10] net: stmmac: dwmac-loongson: Add GNET support Date: Thu, 27 Jul 2023 15:18:53 +0800 Message-Id: <20aa37fdfd4b03b9614befe1c8f78ffc0ac5dead.1690439335.git.chenfeiyang@loongson.cn> X-Mailer: git-send-email 2.39.3 In-Reply-To: References: Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-CM-TRANSID: AQAAf8Ax8uReGsJkn7c8AA--.31333S4 X-CM-SenderInfo: hfkh0wphl1t03j6o00pqjv00gofq/ X-Coremail-Antispam: 1Uk129KBj93XoWxuryDGFyxtw17tw4DAw4fJFc_yoWrur1rp3 y7Aa47Wr97XF13Xws8Jw4DZFyYkrW3trZrWFWxKw43WFZFkrZ0qrySgFW5AF17Cr4DWF1a qr4jkr4UuF4DCwbCm3ZEXasCq-sJn29KB7ZKAUJUUUUf529EdanIXcx71UUUUU7KY7ZEXa sCq-sGcSsGvfJ3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU 0xBIdaVrnRJUUUBCb4IE77IF4wAFF20E14v26r1j6r4UM7CY07I20VC2zVCF04k26cxKx2 IYs7xG6rWj6s0DM7CIcVAFz4kK6r1Y6r17M28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48v e4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI 0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIE14v26r4UJVWxJr1l84ACjcxK6I8E87Iv6xkF7I0E 14v26r4UJVWxJr1ln4kS14v26r126r1DM2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6x kI12xvs2x26I8E6xACxx1l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6xIIjxv20xvE14v2 6Fy26r45twAv7VC2z280aVAFwI0_Cr0_Gr1UMcvjeVCFs4IE7xkEbVWUJVW8JwACjcxG0x vY0x0EwIxGrwCY1x0262kKe7AKxVWUAVWUtwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE 7xkEbVWUJVW8JwCFI7km07C267AKxVWUAVWUtwC20s026c02F40E14v26r1j6r18MI8I3I 0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAI cVC0I7IYx2IY67AKxVWDJVCq3wCI42IY6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F4UJwCI42 IY6xAIw20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Cr0_Gr1UMIIF0xvEx4A2 jsIEc7CjxVAFwI0_Gr1j6F4UJbIYCTnIWIevJa73UjIFyTuYvjxUxNeODUUUU X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net X-Patchwork-Delegate: kuba@kernel.org Add GNET support. Current GNET does not support half duplex mode, and GNET on LS7A only supports ANE when speed is set to 1000M. Signed-off-by: Feiyang Chen --- .../ethernet/stmicro/stmmac/dwmac-loongson.c | 51 +++++++++++++++++++ .../ethernet/stmicro/stmmac/stmmac_ethtool.c | 6 +++ .../net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +- include/linux/stmmac.h | 2 + 4 files changed, 60 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c index 2d6567f0da23..1519c90cf9cf 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c @@ -70,6 +70,55 @@ static struct stmmac_pci_info loongson_gmac_pci_info = { .setup = loongson_gmac_data, }; +static void loongson_gnet_fix_speed(void *priv, unsigned int speed) +{ + struct net_device *ndev = (struct net_device *)(*(unsigned long *)priv); + struct stmmac_priv *ptr = netdev_priv(ndev); + + /* + * The controller and PHY don't work well together. + * We need to use the PS bit to check if the controller's status + * is correct and reset PHY if necessary. + */ + if (speed == SPEED_1000) + if (readl(ptr->ioaddr + MAC_CTRL_REG) & (1 << 15) /* PS */) + phy_restart_aneg(ndev->phydev); +} + +static int loongson_gnet_data(struct pci_dev *pdev, + struct plat_stmmacenet_data *plat) +{ + common_default_data(pdev, plat); + + plat->mdio_bus_data->phy_mask = 0xfffffffb; + + plat->phy_addr = 2; + plat->phy_interface = PHY_INTERFACE_MODE_INTERNAL; + + plat->fix_mac_speed = loongson_gnet_fix_speed; + + /* Get netdev pointer address */ + plat->bsp_priv = &(pdev->dev.driver_data); + + switch (pdev->revision) { + case 0x00: + plat->disable_half_duplex = true; + plat->disable_force_1000 = true; + break; + case 0x01: + plat->disable_half_duplex = true; + break; + default: + break; + } + + return 0; +} + +static struct stmmac_pci_info loongson_gnet_pci_info = { + .setup = loongson_gnet_data, +}; + static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id *id) { @@ -291,9 +340,11 @@ static SIMPLE_DEV_PM_OPS(loongson_dwmac_pm_ops, loongson_dwmac_suspend, loongson_dwmac_resume); #define PCI_DEVICE_ID_LOONGSON_GMAC 0x7a03 +#define PCI_DEVICE_ID_LOONGSON_GNET 0x7a13 static const struct pci_device_id loongson_dwmac_id_table[] = { { PCI_DEVICE_DATA(LOONGSON, GMAC, &loongson_gmac_pci_info) }, + { PCI_DEVICE_DATA(LOONGSON, GNET, &loongson_gnet_pci_info) }, {} }; MODULE_DEVICE_TABLE(pci, loongson_dwmac_id_table); diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c index 2ae73ab842d4..066f42ecf832 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c @@ -404,6 +404,12 @@ stmmac_ethtool_set_link_ksettings(struct net_device *dev, return 0; } + if (priv->plat->disable_force_1000) { + if (cmd->base.speed == SPEED_1000 && + cmd->base.autoneg != AUTONEG_ENABLE) + return -EOPNOTSUPP; + } + return phylink_ethtool_ksettings_set(priv->phylink, cmd); } diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 4f69cad0be42..d0248effdc2e 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1240,7 +1240,7 @@ static int stmmac_phy_setup(struct stmmac_priv *priv) } /* Half-Duplex can only work with single queue */ - if (priv->plat->tx_queues_to_use > 1) + if (priv->plat->tx_queues_to_use > 1 || priv->plat->disable_half_duplex) priv->phylink_config.mac_capabilities &= ~(MAC_10HD | MAC_100HD | MAC_1000HD); priv->phylink_config.mac_managed_pm = true; diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h index 54b9f308aabb..e6852dcfd0c0 100644 --- a/include/linux/stmmac.h +++ b/include/linux/stmmac.h @@ -346,5 +346,7 @@ struct plat_stmmacenet_data { bool dwmac_is_loongson; int has_lgmac; bool disable_flow_control; + bool disable_half_duplex; + bool disable_force_1000; }; #endif