[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20240722153049.GB15209@kernel.org>
Date: Mon, 22 Jul 2024 16:30:49 +0100
From: Simon Horman <horms@...nel.org>
To: Yanteng Si <siyanteng@...ngson.cn>
Cc: andrew@...n.ch, hkallweit1@...il.com, peppe.cavallaro@...com,
alexandre.torgue@...s.st.com, joabreu@...opsys.com,
fancer.lancer@...il.com, diasyzhang@...cent.com,
Jose.Abreu@...opsys.com, chenhuacai@...nel.org,
linux@...linux.org.uk, guyinggang@...ngson.cn,
netdev@...r.kernel.org, chris.chenfeiyang@...il.com,
si.yanteng@...ux.dev, Huacai Chen <chenhuacai@...ngson.cn>
Subject: Re: [PATCH net-next RFC v15 12/14] net: stmmac: dwmac-loongson: Add
Loongson Multi-channels GMAC support
On Mon, Jul 22, 2024 at 07:01:10PM +0800, Yanteng Si wrote:
> The Loongson DWMAC driver currently supports the Loongson GMAC
> devices (based on the DW GMAC v3.50a/v3.73a IP-core) installed to the
> LS2K1000 SoC and LS7A1000 chipset. But recently a new generation
> LS2K2000 SoC was released with the new version of the Loongson GMAC
> synthesized in. The new controller is based on the DW GMAC v3.73a
> IP-core with the AV-feature enabled, which implies the multi
> DMA-channels support. The multi DMA-channels feature has the next
> vendor-specific peculiarities:
>
> 1. Split up Tx and Rx DMA IRQ status/mask bits:
> Name Tx Rx
> DMA_INTR_ENA_NIE = 0x00040000 | 0x00020000;
> DMA_INTR_ENA_AIE = 0x00010000 | 0x00008000;
> DMA_STATUS_NIS = 0x00040000 | 0x00020000;
> DMA_STATUS_AIS = 0x00010000 | 0x00008000;
> DMA_STATUS_FBI = 0x00002000 | 0x00001000;
> 2. Custom Synopsys ID hardwired into the GMAC_VERSION.SNPSVER register
> field. It's 0x10 while it should have been 0x37 in accordance with
> the actual DW GMAC IP-core version.
> 3. There are eight DMA-channels available meanwhile the Synopsys DW
> GMAC IP-core supports up to three DMA-channels.
> 4. It's possible to have each DMA-channel IRQ independently delivered.
> The MSI IRQs must be utilized for that.
>
> Thus in order to have the multi-channels Loongson GMAC controllers
> supported let's modify the Loongson DWMAC driver in accordance with
> all the peculiarities described above:
>
> 1. Create the multi-channels Loongson GMAC-specific
> stmmac_dma_ops::dma_interrupt()
> stmmac_dma_ops::init_chan()
> callbacks due to the non-standard DMA IRQ CSR flags layout.
> 2. Create the Loongson DWMAC-specific platform setup() method
> which gets to initialize the DMA-ops with the dwmac1000_dma_ops
> instance and overrides the callbacks described in 1. The method also
> overrides the custom Synopsys ID with the real one in order to have
> the rest of the HW-specific callbacks correctly detected by the driver
> core.
> 3. Make sure the platform setup() method enables the flow control and
> duplex modes supported by the controller.
>
> Signed-off-by: Feiyang Chen <chenfeiyang@...ngson.cn>
> Signed-off-by: Yinggang Gu <guyinggang@...ngson.cn>
> Acked-by: Huacai Chen <chenhuacai@...ngson.cn>
> Signed-off-by: Yanteng Si <siyanteng@...ngson.cn>
...
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
> +static struct mac_device_info *loongson_dwmac_setup(void *apriv)
> +{
> + struct stmmac_priv *priv = apriv;
> + struct mac_device_info *mac;
> + struct stmmac_dma_ops *dma;
> + struct loongson_data *ld;
> + struct pci_dev *pdev;
> +
> + ld = priv->plat->bsp_priv;
> + pdev = to_pci_dev(priv->device);
nit: pdev is set but otherwise unused.
Flagged by allmodconfig W=1 builds
> +
> + mac = devm_kzalloc(priv->device, sizeof(*mac), GFP_KERNEL);
> + if (!mac)
> + return NULL;
> +
> + dma = devm_kzalloc(priv->device, sizeof(*dma), GFP_KERNEL);
> + if (!dma)
> + return NULL;
> +
> + /* The Loongson GMAC devices are based on the DW GMAC
> + * v3.50a and v3.73a IP-cores. But the HW designers have changed the
> + * GMAC_VERSION.SNPSVER field to the custom 0x10 value on the
> + * network controllers with the multi-channels feature
> + * available to emphasize the differences: multiple DMA-channels,
> + * AV feature and GMAC_INT_STATUS CSR flags layout. Get back the
> + * original value so the correct HW-interface would be selected.
> + */
> + if (ld->loongson_id == DWMAC_CORE_LS_MULTICHAN) {
> + priv->synopsys_id = DWMAC_CORE_3_70;
> + *dma = dwmac1000_dma_ops;
> + dma->init_chan = loongson_dwmac_dma_init_channel;
> + dma->dma_interrupt = loongson_dwmac_dma_interrupt;
> + mac->dma = dma;
> + }
> +
> + priv->dev->priv_flags |= IFF_UNICAST_FLT;
> +
> + /* Pre-initialize the respective "mac" fields as it's done in
> + * dwmac1000_setup()
> + */
> + mac->pcsr = priv->ioaddr;
> + mac->multicast_filter_bins = priv->plat->multicast_filter_bins;
> + mac->unicast_filter_entries = priv->plat->unicast_filter_entries;
> + mac->mcast_bits_log2 = 0;
> +
> + if (mac->multicast_filter_bins)
> + mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins);
> +
> + /* Loongson GMAC doesn't support the flow control. */
> + mac->link.caps = MAC_10 | MAC_100 | MAC_1000;
> +
> + mac->link.duplex = GMAC_CONTROL_DM;
> + mac->link.speed10 = GMAC_CONTROL_PS;
> + mac->link.speed100 = GMAC_CONTROL_PS | GMAC_CONTROL_FES;
> + mac->link.speed1000 = 0;
> + mac->link.speed_mask = GMAC_CONTROL_PS | GMAC_CONTROL_FES;
> + mac->mii.addr = GMAC_MII_ADDR;
> + mac->mii.data = GMAC_MII_DATA;
> + mac->mii.addr_shift = 11;
> + mac->mii.addr_mask = 0x0000F800;
> + mac->mii.reg_shift = 6;
> + mac->mii.reg_mask = 0x000007C0;
> + mac->mii.clk_csr_shift = 2;
> + mac->mii.clk_csr_mask = GENMASK(5, 2);
> +
> + return mac;
> +}
...
Powered by blists - more mailing lists