diff mbox series

[net-next,v8,07/11] net: stmmac: dwmac-loongson: Add multi-channel supports for loongson

Message ID bec0d6bf78c0dcf4797a148e3509058e46ccdb13.1706601050.git.siyanteng@loongson.cn (mailing list archive)
State Changes Requested
Delegated to: Netdev Maintainers
Headers show
Series stmmac: Add Loongson platform support | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for net-next
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit fail Errors and warnings before: 1053 this patch: 1053
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers success CCed 0 of 0 maintainers
netdev/build_clang fail Errors and warnings before: 1070 this patch: 1070
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn fail Errors and warnings before: 1070 this patch: 1070
netdev/checkpatch warning WARNING: line length of 81 exceeds 80 columns
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Yanteng Si Jan. 30, 2024, 8:48 a.m. UTC
Request allocation for MSI for specific versions.

Some features of Loongson platforms are bound to the GMAC_VERSION
register. We have to read its value in order to get the correct channel
number.

Signed-off-by: Yanteng Si <siyanteng@loongson.cn>
Signed-off-by: Feiyang Chen <chenfeiyang@loongson.cn>
Signed-off-by: Yinggang Gu <guyinggang@loongson.cn>
---
 .../ethernet/stmicro/stmmac/dwmac-loongson.c  | 57 +++++++++++++++----
 1 file changed, 46 insertions(+), 11 deletions(-)

Comments

Serge Semin Feb. 5, 2024, 9:28 p.m. UTC | #1
On Tue, Jan 30, 2024 at 04:48:19PM +0800, Yanteng Si wrote:
> Request allocation for MSI for specific versions.
>

Please elaborate what is actually done in the patch. What device
version it is dedicated for (Loongson GNET?), what IRQs the patch
adds, etc.

BTW will GNET device work without this patch? If no you need to either
merge it into the patch introducing the GNET-device support or place
it before that patch (6/11).
 
> Some features of Loongson platforms are bound to the GMAC_VERSION
> register. We have to read its value in order to get the correct channel
> number.

This message seems misleading. I don't see you doing that in the patch below...

> 
> Signed-off-by: Yanteng Si <siyanteng@loongson.cn>
> Signed-off-by: Feiyang Chen <chenfeiyang@loongson.cn>
> Signed-off-by: Yinggang Gu <guyinggang@loongson.cn>
> ---
>  .../ethernet/stmicro/stmmac/dwmac-loongson.c  | 57 +++++++++++++++----
>  1 file changed, 46 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
> index 584f7322bd3e..60d0a122d7c9 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
> @@ -98,10 +98,10 @@ static void dwlgmac_dma_init_channel(struct stmmac_priv *priv,
>  	if (dma_cfg->aal)
>  		value |= DMA_BUS_MODE_AAL;
> 
 
> -	writel(value, ioaddr + DMA_BUS_MODE);
> +	writel(value, ioaddr + DMA_CHAN_BUS_MODE(chan));
>  
>  	/* Mask interrupts by writing to CSR7 */
> -	writel(DMA_INTR_DEFAULT_MASK_LOONGSON, ioaddr + DMA_INTR_ENA);
> +	writel(DMA_INTR_DEFAULT_MASK_LOONGSON, ioaddr + DMA_CHAN_INTR_ENA(chan));

Em, why is this here? There is a patch
[PATCH net-next v8 05/11] net: stmmac: dwmac-loongson: Add Loongson-specific register definitions
in this series which was supposed to introduce the fully functional
GNET-specific callbacks. Move this change in there.

>  }
>  
>  static int dwlgmac_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr,
> @@ -238,6 +238,45 @@ static int loongson_dwmac_config_legacy(struct pci_dev *pdev,
>  	return 0;
>  }
>  

> +static int loongson_dwmac_config_multi_msi(struct pci_dev *pdev,

This method seems like the GNET-specific one. What about using the
appropriate prefix then?

> +					   struct plat_stmmacenet_data *plat,
> +					   struct stmmac_resources *res,
> +					   struct device_node *np,

> +					   int channel_num)

Why do you need this parametrization? Since this method is
GNET-specific what about defining a macro with the channels amount and
using it here?

> +{
> +	int i, ret, vecs;
> +
> +	vecs = roundup_pow_of_two(channel_num * 2 + 1);
> +	ret = pci_alloc_irq_vectors(pdev, vecs, vecs, PCI_IRQ_MSI);

> +	if (ret < 0) {
> +		dev_info(&pdev->dev,
> +			 "MSI enable failed, Fallback to legacy interrupt\n");
> +		return loongson_dwmac_config_legacy(pdev, plat, res, np);

In what conditions is this possible? Will the
loongson_dwmac_config_legacy() method work in that case? Did you test
it out?

> +	}
> +

> +	plat->rx_queues_to_use = channel_num;
> +	plat->tx_queues_to_use = channel_num;

This is supposed to be initialized in the setup() methods. Please move
it to the dedicated patch.

> +
> +	res->irq = pci_irq_vector(pdev, 0);

> +	res->wol_irq = res->irq;

Once again. wol_irq is optional. If there is no dedicated WoL IRQ
leave the field as zero.

> +
> +	/* INT NAME | MAC | CH7 rx | CH7 tx | ... | CH0 rx | CH0 tx |
> +	 * --------- ----- -------- --------  ...  -------- --------
> +	 * IRQ NUM  |  0  |   1    |   2    | ... |   15   |   16   |
> +	 */
> +	for (i = 0; i < channel_num; i++) {
> +		res->rx_irq[channel_num - 1 - i] =
> +			pci_irq_vector(pdev, 1 + i * 2);
> +		res->tx_irq[channel_num - 1 - i] =
> +			pci_irq_vector(pdev, 2 + i * 2);
> +	}
> +
> +	plat->flags |= STMMAC_FLAG_MULTI_MSI_EN;

> +	dev_info(&pdev->dev, "%s: multi MSI enablement successful\n", __func__);

What's the point in printing this message especially with the __func__
prefix?  You'll always be able to figure out the allocated IRQs by
means of procfs. I suggest to drop it.

> +
> +	return 0;
> +}
> +

>  static void loongson_default_data(struct pci_dev *pdev,
>  				  struct plat_stmmacenet_data *plat)
>  {
> @@ -296,11 +335,8 @@ static int loongson_gmac_config(struct pci_dev *pdev,
>  				struct stmmac_resources *res,
>  				struct device_node *np)
>  {
> -	int ret;
> -
> -	ret = loongson_dwmac_config_legacy(pdev, plat, res, np);
>  
> -	return ret;
> +	return 0;
>  }
>  
>  static struct stmmac_pci_info loongson_gmac_pci_info = {
> @@ -380,11 +416,7 @@ static int loongson_gnet_config(struct pci_dev *pdev,
>  				struct stmmac_resources *res,
>  				struct device_node *np)
>  {
> -	int ret;
> -
> -	ret = loongson_dwmac_config_legacy(pdev, plat, res, np);
> -
> -	return ret;
> +	return 0;
>  }

Here you are dropping the changes you just introduced leaving the
config() methods empty... Why not to place the
loongson_dwmac_config_legacy() invocation in the probe() method right
at the patches introducing the config() functions and not to add the
config() callback in the first place?

-Serge(y)

>  
>  static struct stmmac_pci_info loongson_gnet_pci_info = {
> @@ -483,6 +515,9 @@ static int loongson_dwmac_probe(struct pci_dev *pdev,
>  		ld->dwlgmac_dma_ops.dma_interrupt = dwlgmac_dma_interrupt;
>  
>  		plat->setup = loongson_setup;
> +		ret = loongson_dwmac_config_multi_msi(pdev, plat, &res, np, 8);
> +	} else {
> +		ret = loongson_dwmac_config_legacy(pdev, plat, &res, np);
>  	}
>  
>  	plat->bsp_priv = ld;
> -- 
> 2.31.4
>
Yanteng Si March 14, 2024, 1:13 p.m. UTC | #2
在 2024/3/14 17:33, Yanteng Si 写道:
> 在 2024/2/6 05:28, Serge Semin 写道:
> > On Tue, Jan 30, 2024 at 04:48:19PM +0800, Yanteng Si wrote:
> >> Request allocation for MSI for specific versions.
> >>
> > Please elaborate what is actually done in the patch. What device
> > version it is dedicated for (Loongson GNET?), what IRQs the patch
> > adds, etc.
> gnet_device   core IP    IRQ
> 7a2000        0x37    legacy
> 2k2000        0x10    multi_msi
> >
> > BTW will GNET device work without this patch? If no you need to either
> > merge it into the patch introducing the GNET-device support or place
> > it before that patch (6/11).
> OK, GNET device work need this patch.
> >   
> >> Some features of Loongson platforms are bound to the GMAC_VERSION
> >> register. We have to read its value in order to get the correct channel
> >> number.
> > This message seems misleading. I don't see you doing that in the patch below...
> Because part of our gnet hardware (7a2000) core IP is 0x37
> >
> >> Signed-off-by: Yanteng Si<siyanteng@loongson.cn>
> >> Signed-off-by: Feiyang Chen<chenfeiyang@loongson.cn>
> >> Signed-off-by: Yinggang Gu<guyinggang@loongson.cn>
> >> ---
> >>   .../ethernet/stmicro/stmmac/dwmac-loongson.c  | 57 +++++++++++++++----
> >>   1 file changed, 46 insertions(+), 11 deletions(-)
> >>
> >> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
> >> index 584f7322bd3e..60d0a122d7c9 100644
> >> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
> >> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
> >> @@ -98,10 +98,10 @@ static void dwlgmac_dma_init_channel(struct stmmac_priv *priv,
> >>   	if (dma_cfg->aal)
> >>   		value |= DMA_BUS_MODE_AAL;
> >>
> >   
> >> -	writel(value, ioaddr + DMA_BUS_MODE);
> >> +	writel(value, ioaddr + DMA_CHAN_BUS_MODE(chan));
> >>   
> >>   	/* Mask interrupts by writing to CSR7 */
> >> -	writel(DMA_INTR_DEFAULT_MASK_LOONGSON, ioaddr + DMA_INTR_ENA);
> >> +	writel(DMA_INTR_DEFAULT_MASK_LOONGSON, ioaddr + DMA_CHAN_INTR_ENA(chan));
> > Em, why is this here? There is a patch
> > [PATCH net-next v8 05/11] net: stmmac: dwmac-loongson: Add Loongson-specific register definitions
> > in this series which was supposed to introduce the fully functional
> > GNET-specific callbacks. Move this change in there.
> OK.
> >
> >>   }
> >>   
> >>   static int dwlgmac_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr,
> >> @@ -238,6 +238,45 @@ static int loongson_dwmac_config_legacy(struct pci_dev *pdev,
> >>   	return 0;
> >>   }
> >>   
> >> +static int loongson_dwmac_config_multi_msi(struct pci_dev *pdev,
> > This method seems like the GNET-specific one. What about using the
> > appropriate prefix then?
> OK. loongson_gnet_config_multi_msi()
>
> >
> >> +					   struct plat_stmmacenet_data *plat,
> >> +					   struct stmmac_resources *res,
> >> +					   struct device_node *np,
> >> +					   int channel_num)
> > Why do you need this parametrization? Since this method is
> > GNET-specific what about defining a macro with the channels amount and
> > using it here?
>
> OK.
>
> #define CHANNEL_NUM    8
>
> >
> >> +{
> >> +	int i, ret, vecs;
> >> +
> >> +	vecs = roundup_pow_of_two(channel_num * 2 + 1);
> >> +	ret = pci_alloc_irq_vectors(pdev, vecs, vecs, PCI_IRQ_MSI);
> >> +	if (ret < 0) {
> >> +		dev_info(&pdev->dev,
> >> +			 "MSI enable failed, Fallback to legacy interrupt\n");
> >> +		return loongson_dwmac_config_legacy(pdev, plat, res, np);
> > In what conditions is this possible? Will the
> > loongson_dwmac_config_legacy() method work in that case? Did you test
> > it out?
> Failed to apply for msi interrupt when the interrupt number is not enough,For
> example, there are a large number of devices。
> >> +	}
> >> +
> >> +	plat->rx_queues_to_use = channel_num;
> >> +	plat->tx_queues_to_use = channel_num;
> > This is supposed to be initialized in the setup() methods. Please move
> > it to the dedicated patch.
> No, referring to my previous reply, only the 0x10 gnet device has 8 channels,
> and the 0x37 device has a single channel.
> >
> >> +
> >> +	res->irq = pci_irq_vector(pdev, 0);
> >> +	res->wol_irq = res->irq;
> > Once again. wol_irq is optional. If there is no dedicated WoL IRQ
> > leave the field as zero.
> OK.
>
> res->wol_irq = 0;
>
> >
> >> +
> >> +	/* INT NAME | MAC | CH7 rx | CH7 tx | ... | CH0 rx | CH0 tx |
> >> +	 * --------- ----- -------- --------  ...  -------- --------
> >> +	 * IRQ NUM  |  0  |   1    |   2    | ... |   15   |   16   |
> >> +	 */
> >> +	for (i = 0; i < channel_num; i++) {
> >> +		res->rx_irq[channel_num - 1 - i] =
> >> +			pci_irq_vector(pdev, 1 + i * 2);
> >> +		res->tx_irq[channel_num - 1 - i] =
> >> +			pci_irq_vector(pdev, 2 + i * 2);
> >> +	}
> >> +
> >> +	plat->flags |= STMMAC_FLAG_MULTI_MSI_EN;
> >> +	dev_info(&pdev->dev, "%s: multi MSI enablement successful\n", __func__);
> > What's the point in printing this message especially with the __func__
> > prefix?  You'll always be able to figure out the allocated IRQs by
> > means of procfs. I suggest to drop it.
>
> OK.
>
> >
> >> +
> >> +	return 0;
> >> +}
> >> +
> >>   static void loongson_default_data(struct pci_dev *pdev,
> >>   				  struct plat_stmmacenet_data *plat)
> >>   {
> >> @@ -296,11 +335,8 @@ static int loongson_gmac_config(struct pci_dev *pdev,
> >>   				struct stmmac_resources *res,
> >>   				struct device_node *np)
> >>   {
> >> -	int ret;
> >> -
> >> -	ret = loongson_dwmac_config_legacy(pdev, plat, res, np);
> >>   
> >> -	return ret;
> >> +	return 0;
> >>   }
> >>   
> >>   static struct stmmac_pci_info loongson_gmac_pci_info = {
> >> @@ -380,11 +416,7 @@ static int loongson_gnet_config(struct pci_dev *pdev,
> >>   				struct stmmac_resources *res,
> >>   				struct device_node *np)
> >>   {
> >> -	int ret;
> >> -
> >> -	ret = loongson_dwmac_config_legacy(pdev, plat, res, np);
> >> -
> >> -	return ret;
> >> +	return 0;
> >>   }
> > Here you are dropping the changes you just introduced leaving the
> > config() methods empty... Why not to place the
> > loongson_dwmac_config_legacy() invocation in the probe() method right
> > at the patches introducing the config() functions and not to add the
> > config() callback in the first place?
> OK, I will try.
>
> Thanks,
>
> Yanteng
>
> >
> > -Serge(y)
> >
> >>   
> >>   static struct stmmac_pci_info loongson_gnet_pci_info = {
> >> @@ -483,6 +515,9 @@ static int loongson_dwmac_probe(struct pci_dev *pdev,
> >>   		ld->dwlgmac_dma_ops.dma_interrupt = dwlgmac_dma_interrupt;
> >>   
> >>   		plat->setup = loongson_setup;
> >> +		ret = loongson_dwmac_config_multi_msi(pdev, plat, &res, np, 8);
> >> +	} else {
> >> +		ret = loongson_dwmac_config_legacy(pdev, plat, &res, np);
> >>   	}
> >>   
> >>   	plat->bsp_priv = ld;
> >> -- 
> >> 2.31.4
> >>
Serge Semin March 19, 2024, 3:53 p.m. UTC | #3
On Thu, Mar 14, 2024 at 09:13:58PM +0800, Yanteng Si wrote:
> 
> 在 2024/3/14 17:33, Yanteng Si 写道:
> > 在 2024/2/6 05:28, Serge Semin 写道:
> > > On Tue, Jan 30, 2024 at 04:48:19PM +0800, Yanteng Si wrote:
> > >> Request allocation for MSI for specific versions.
> > >>
> > > Please elaborate what is actually done in the patch. What device
> > > version it is dedicated for (Loongson GNET?), what IRQs the patch
> > > adds, etc.
> > gnet_device   core IP    IRQ
> > 7a2000        0x37    legacy
> > 2k2000        0x10    multi_msi
> > >
> > > BTW will GNET device work without this patch? If no you need to either
> > > merge it into the patch introducing the GNET-device support or place
> > > it before that patch (6/11).
> > OK, GNET device work need this patch.
> > >   >> Some features of Loongson platforms are bound to the GMAC_VERSION
> > >> register. We have to read its value in order to get the correct channel
> > >> number.
> > > This message seems misleading. I don't see you doing that in the patch below...
> > Because part of our gnet hardware (7a2000) core IP is 0x37
> > >
> > >> Signed-off-by: Yanteng Si<siyanteng@loongson.cn>
> > >> Signed-off-by: Feiyang Chen<chenfeiyang@loongson.cn>
> > >> Signed-off-by: Yinggang Gu<guyinggang@loongson.cn>
> > >> ---
> > >>   .../ethernet/stmicro/stmmac/dwmac-loongson.c  | 57 +++++++++++++++----
> > >>   1 file changed, 46 insertions(+), 11 deletions(-)
> > >>
> > >> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
> > >> index 584f7322bd3e..60d0a122d7c9 100644
> > >> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
> > >> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
> > >> @@ -98,10 +98,10 @@ static void dwlgmac_dma_init_channel(struct stmmac_priv *priv,
> > >>   	if (dma_cfg->aal)
> > >>   		value |= DMA_BUS_MODE_AAL;
> > >>
> > >   >> -	writel(value, ioaddr + DMA_BUS_MODE);
> > >> +	writel(value, ioaddr + DMA_CHAN_BUS_MODE(chan));
> > >>   >>   	/* Mask interrupts by writing to CSR7 */
> > >> -	writel(DMA_INTR_DEFAULT_MASK_LOONGSON, ioaddr + DMA_INTR_ENA);
> > >> +	writel(DMA_INTR_DEFAULT_MASK_LOONGSON, ioaddr + DMA_CHAN_INTR_ENA(chan));
> > > Em, why is this here? There is a patch
> > > [PATCH net-next v8 05/11] net: stmmac: dwmac-loongson: Add Loongson-specific register definitions
> > > in this series which was supposed to introduce the fully functional
> > > GNET-specific callbacks. Move this change in there.
> > OK.
> > >
> > >>   }
> > >>   >>   static int dwlgmac_dma_interrupt(struct stmmac_priv *priv,
> > void __iomem *ioaddr,
> > >> @@ -238,6 +238,45 @@ static int loongson_dwmac_config_legacy(struct pci_dev *pdev,
> > >>   	return 0;
> > >>   }
> > >>   >> +static int loongson_dwmac_config_multi_msi(struct pci_dev
> > *pdev,
> > > This method seems like the GNET-specific one. What about using the
> > > appropriate prefix then?
> > OK. loongson_gnet_config_multi_msi()
> > 
> > >
> > >> +					   struct plat_stmmacenet_data *plat,
> > >> +					   struct stmmac_resources *res,
> > >> +					   struct device_node *np,
> > >> +					   int channel_num)
> > > Why do you need this parametrization? Since this method is
> > > GNET-specific what about defining a macro with the channels amount and
> > > using it here?
> > 
> > OK.
> > 
> > #define CHANNEL_NUM    8
> > 
> > >
> > >> +{
> > >> +	int i, ret, vecs;
> > >> +
> > >> +	vecs = roundup_pow_of_two(channel_num * 2 + 1);
> > >> +	ret = pci_alloc_irq_vectors(pdev, vecs, vecs, PCI_IRQ_MSI);
> > >> +	if (ret < 0) {
> > >> +		dev_info(&pdev->dev,
> > >> +			 "MSI enable failed, Fallback to legacy interrupt\n");
> > >> +		return loongson_dwmac_config_legacy(pdev, plat, res, np);
> > > In what conditions is this possible? Will the
> > > loongson_dwmac_config_legacy() method work in that case? Did you test
> > > it out?

> > Failed to apply for msi interrupt when the interrupt number is not enough,For
> > example, there are a large number of devices。

Then those platforms will _require_ to have the DT-node specified. This
will define the DT-bindings which I doubt you imply here. Am I wrong?

Once again have you tested the loongson_dwmac_config_legacy() method
working in the case of the pci_alloc_irq_vectors() failure?
	

> > >> +	}
> > >> +
> > >> +	plat->rx_queues_to_use = channel_num;
> > >> +	plat->tx_queues_to_use = channel_num;
> > > This is supposed to be initialized in the setup() methods. Please move
> > > it to the dedicated patch.

> > No, referring to my previous reply, only the 0x10 gnet device has 8 channels,
> > and the 0x37 device has a single channel.

Yes. You have a perfectly suitable method for it. It's
loongson_gnet_data(). Init the number of channels there based on the
value read from the GMAC_VERSION.SNPSVER field. Thus the
loongson_gnet_config_multi_msi() will get to be more coherent setting
up the MSI IRQs only.

Am I missing something in the last two notes chunks regard? If yes,
let's submit v9 as you see it. We'll get back to this part there then.

-Serge(y)

> > >
> > >> +
> > >> +	res->irq = pci_irq_vector(pdev, 0);
> > >> +	res->wol_irq = res->irq;
> > > Once again. wol_irq is optional. If there is no dedicated WoL IRQ
> > > leave the field as zero.
> > OK.
> > 
> > res->wol_irq = 0;
> > 
> > >
> > >> +
> > >> +	/* INT NAME | MAC | CH7 rx | CH7 tx | ... | CH0 rx | CH0 tx |
> > >> +	 * --------- ----- -------- --------  ...  -------- --------
> > >> +	 * IRQ NUM  |  0  |   1    |   2    | ... |   15   |   16   |
> > >> +	 */
> > >> +	for (i = 0; i < channel_num; i++) {
> > >> +		res->rx_irq[channel_num - 1 - i] =
> > >> +			pci_irq_vector(pdev, 1 + i * 2);
> > >> +		res->tx_irq[channel_num - 1 - i] =
> > >> +			pci_irq_vector(pdev, 2 + i * 2);
> > >> +	}
> > >> +
> > >> +	plat->flags |= STMMAC_FLAG_MULTI_MSI_EN;
> > >> +	dev_info(&pdev->dev, "%s: multi MSI enablement successful\n", __func__);
> > > What's the point in printing this message especially with the __func__
> > > prefix?  You'll always be able to figure out the allocated IRQs by
> > > means of procfs. I suggest to drop it.
> > 
> > OK.
> > 
> > >
> > >> +
> > >> +	return 0;
> > >> +}
> > >> +
> > >>   static void loongson_default_data(struct pci_dev *pdev,
> > >>   				  struct plat_stmmacenet_data *plat)
> > >>   {
> > >> @@ -296,11 +335,8 @@ static int loongson_gmac_config(struct pci_dev *pdev,
> > >>   				struct stmmac_resources *res,
> > >>   				struct device_node *np)
> > >>   {
> > >> -	int ret;
> > >> -
> > >> -	ret = loongson_dwmac_config_legacy(pdev, plat, res, np);
> > >>   >> -	return ret;
> > >> +	return 0;
> > >>   }
> > >>   >>   static struct stmmac_pci_info loongson_gmac_pci_info = {
> > >> @@ -380,11 +416,7 @@ static int loongson_gnet_config(struct pci_dev *pdev,
> > >>   				struct stmmac_resources *res,
> > >>   				struct device_node *np)
> > >>   {
> > >> -	int ret;
> > >> -
> > >> -	ret = loongson_dwmac_config_legacy(pdev, plat, res, np);
> > >> -
> > >> -	return ret;
> > >> +	return 0;
> > >>   }
> > > Here you are dropping the changes you just introduced leaving the
> > > config() methods empty... Why not to place the
> > > loongson_dwmac_config_legacy() invocation in the probe() method right
> > > at the patches introducing the config() functions and not to add the
> > > config() callback in the first place?
> > OK, I will try.
> > 
> > Thanks,
> > 
> > Yanteng
> > 
> > >
> > > -Serge(y)
> > >
> > >>   >>   static struct stmmac_pci_info loongson_gnet_pci_info = {
> > >> @@ -483,6 +515,9 @@ static int loongson_dwmac_probe(struct pci_dev *pdev,
> > >>   		ld->dwlgmac_dma_ops.dma_interrupt = dwlgmac_dma_interrupt;
> > >>   >>   		plat->setup = loongson_setup;
> > >> +		ret = loongson_dwmac_config_multi_msi(pdev, plat, &res, np, 8);
> > >> +	} else {
> > >> +		ret = loongson_dwmac_config_legacy(pdev, plat, &res, np);
> > >>   	}
> > >>   >>   	plat->bsp_priv = ld;
> > >> -- >> 2.31.4
> > >>
>
Yanteng Si March 22, 2024, 10:36 a.m. UTC | #4
>>>>> +{
>>>>> +	int i, ret, vecs;
>>>>> +
>>>>> +	vecs = roundup_pow_of_two(channel_num * 2 + 1);
>>>>> +	ret = pci_alloc_irq_vectors(pdev, vecs, vecs, PCI_IRQ_MSI);
>>>>> +	if (ret < 0) {
>>>>> +		dev_info(&pdev->dev,
>>>>> +			 "MSI enable failed, Fallback to legacy interrupt\n");
>>>>> +		return loongson_dwmac_config_legacy(pdev, plat, res, np);
>>>> In what conditions is this possible? Will the
>>>> loongson_dwmac_config_legacy() method work in that case? Did you test
>>>> it out?
I need to wait for special hardware and PMON for this.  Please give me 
some time.

> Then those platforms will _require_ to have the DT-node specified. This
> will define the DT-bindings which I doubt you imply here. Am I wrong?
>
> Once again have you tested the loongson_dwmac_config_legacy() method
> working in the case of the pci_alloc_irq_vectors() failure?

Yes!  I have tested it, it works in single channel mode.

dmesg:

[    3.935203] mdio_bus stmmac-18:02: attached PHY driver [unbound]
(mii_bus:phy_addr=stmmac-18:02, irq=POLL)
[    3.945625] dwmac-loongson-pci 0000:00:03.1: MSI enable failed, Fallback to
legacy interrupt
[    3.954175] dwmac-loongson-pci 0000:00:03.1: User ID: 0xd1, Synopsys ID: 0x10
[    3.973676] dwmac-loongson-pci 0000:00:03.1: DMA HW capability register supported
[    3.981135] dwmac-loongson-pci 0000:00:03.1: RX Checksum Offload Engine supported

cat /proc/interrupt:

43:          0          0   PCH PIC  16  ahci[0000:00:08.0]
   44:          0          0   PCH PIC  12  enp0s3f0
   45:          0          0   PCH PIC  14  enp0s3f1
   46:      16233          0   PCH PIC  17  enp0s3f2
   47:      12698          0   PCH PIC  48  xhci-hcd:usb1


the irq number 46 is the falkback legacy irq.

> 	
>
>>>>> +	}
>>>>> +
>>>>> +	plat->rx_queues_to_use = channel_num;
>>>>> +	plat->tx_queues_to_use = channel_num;
>>>> This is supposed to be initialized in the setup() methods. Please move
>>>> it to the dedicated patch.
>>> No, referring to my previous reply, only the 0x10 gnet device has 8 channels,
>>> and the 0x37 device has a single channel.
> Yes. You have a perfectly suitable method for it. It's
> loongson_gnet_data(). Init the number of channels there based on the
> value read from the GMAC_VERSION.SNPSVER field. Thus the
> loongson_gnet_config_multi_msi() will get to be more coherent setting
> up the MSI IRQs only.
You are right!  it works well.


Thanks,

Yanteng
Serge Semin March 22, 2024, 6:47 p.m. UTC | #5
On Fri, Mar 22, 2024 at 06:36:20PM +0800, Yanteng Si wrote:
> > > > > > +{
> > > > > > +	int i, ret, vecs;
> > > > > > +
> > > > > > +	vecs = roundup_pow_of_two(channel_num * 2 + 1);
> > > > > > +	ret = pci_alloc_irq_vectors(pdev, vecs, vecs, PCI_IRQ_MSI);
> > > > > > +	if (ret < 0) {
> > > > > > +		dev_info(&pdev->dev,
> > > > > > +			 "MSI enable failed, Fallback to legacy interrupt\n");
> > > > > > +		return loongson_dwmac_config_legacy(pdev, plat, res, np);
> > > > > In what conditions is this possible? Will the
> > > > > loongson_dwmac_config_legacy() method work in that case? Did you test
> > > > > it out?
> I need to wait for special hardware and PMON for this.  Please give me some
> time.
> 
> > Then those platforms will _require_ to have the DT-node specified. This
> > will define the DT-bindings which I doubt you imply here. Am I wrong?
> > 
> > Once again have you tested the loongson_dwmac_config_legacy() method
> > working in the case of the pci_alloc_irq_vectors() failure?
> 
> Yes!  I have tested it, it works in single channel mode.
> 
> dmesg:
> 
> [    3.935203] mdio_bus stmmac-18:02: attached PHY driver [unbound]
> (mii_bus:phy_addr=stmmac-18:02, irq=POLL)
> [    3.945625] dwmac-loongson-pci 0000:00:03.1: MSI enable failed, Fallback to
> legacy interrupt
> [    3.954175] dwmac-loongson-pci 0000:00:03.1: User ID: 0xd1, Synopsys ID: 0x10
> [    3.973676] dwmac-loongson-pci 0000:00:03.1: DMA HW capability register supported
> [    3.981135] dwmac-loongson-pci 0000:00:03.1: RX Checksum Offload Engine supported
> 
> cat /proc/interrupt:
> 
> 43:          0          0   PCH PIC  16  ahci[0000:00:08.0]
>   44:          0          0   PCH PIC  12  enp0s3f0
>   45:          0          0   PCH PIC  14  enp0s3f1
>   46:      16233          0   PCH PIC  17  enp0s3f2
>   47:      12698          0   PCH PIC  48  xhci-hcd:usb1
> 
> 
> the irq number 46 is the falkback legacy irq.

Ok. Thanks. You can do that in a bit more clever manner. Like this:

+static int loongson_dwmac_config_multi_msi(struct pci_dev *pdev,
+					   struct plat_stmmacenet_data *plat,
+					   struct stmmac_resources *res)
+{
+	int i, ret, vecs;
+
+	/* INT NAME | MAC | CH7 rx | CH7 tx | ... | CH0 rx | CH0 tx |
+	 * --------- ----- -------- --------  ...  -------- --------
+	 * IRQ NUM  |  0  |   1    |   2    | ... |   15   |   16   |
+	 */
+	vecs = plat->rx_queues_to_use + plat->tx_queues_to_use + 1;
+	ret = pci_alloc_irq_vectors(pdev, 1, vecs, PCI_IRQ_MSI | PCI_IRQ_LEGACY);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Failed to allocate PCI IRQs\n");
+		return ret;
+	} else if (ret >= vecs) {
+		for (i = 0; i < plat->rx_queues_to_use; i++) {
+			res->rx_irq[CHANNELS_NUM - 1 - i] =
+				pci_irq_vector(pdev, 1 + i * 2);
+		}
+		for (i = 0; i < plat->tx_queues_to_use; i++) {
+			res->tx_irq[CHANNELS_NUM - 1 - i] =
+				pci_irq_vector(pdev, 2 + i * 2);
+		}
+
+		plat->flags |= STMMAC_FLAG_MULTI_MSI_EN;
+	}
+
+	res->irq = pci_irq_vector(pdev, 0);
+
+	return 0;
+}

Thus in case if for some reason you were able to allocate less MSI
IRQs than required you'll still be able to use them. The legacy IRQ
will be also available in case if MSI failed to be allocated.

-Serge(y)

> 
> > 	
> > 
> > > > > > +	}
> > > > > > +
> > > > > > +	plat->rx_queues_to_use = channel_num;
> > > > > > +	plat->tx_queues_to_use = channel_num;
> > > > > This is supposed to be initialized in the setup() methods. Please move
> > > > > it to the dedicated patch.
> > > > No, referring to my previous reply, only the 0x10 gnet device has 8 channels,
> > > > and the 0x37 device has a single channel.
> > Yes. You have a perfectly suitable method for it. It's
> > loongson_gnet_data(). Init the number of channels there based on the
> > value read from the GMAC_VERSION.SNPSVER field. Thus the
> > loongson_gnet_config_multi_msi() will get to be more coherent setting
> > up the MSI IRQs only.
> You are right!  it works well.
> 
> 
> Thanks,
> 
> Yanteng
> 
>
Yanteng Si April 3, 2024, 8:09 a.m. UTC | #6
在 2024/3/23 02:47, Serge Semin 写道:
> +static int loongson_dwmac_config_multi_msi(struct pci_dev *pdev,
> +					   struct plat_stmmacenet_data *plat,
> +					   struct stmmac_resources *res)
> +{
> +	int i, ret, vecs;
> +
> +	/* INT NAME | MAC | CH7 rx | CH7 tx | ... | CH0 rx | CH0 tx |
> +	 * --------- ----- -------- --------  ...  -------- --------
> +	 * IRQ NUM  |  0  |   1    |   2    | ... |   15   |   16   |
> +	 */
> +	vecs = plat->rx_queues_to_use + plat->tx_queues_to_use + 1;
> +	ret = pci_alloc_irq_vectors(pdev, 1, vecs, PCI_IRQ_MSI | PCI_IRQ_LEGACY);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "Failed to allocate PCI IRQs\n");
> +		return ret;
> +	} else if (ret >= vecs) {
> +		for (i = 0; i < plat->rx_queues_to_use; i++) {
> +			res->rx_irq[CHANNELS_NUM - 1 - i] =
> +				pci_irq_vector(pdev, 1 + i * 2);
> +		}
> +		for (i = 0; i < plat->tx_queues_to_use; i++) {
> +			res->tx_irq[CHANNELS_NUM - 1 - i] =
> +				pci_irq_vector(pdev, 2 + i * 2);
> +		}
> +
> +		plat->flags |= STMMAC_FLAG_MULTI_MSI_EN;
> +	}
> +
> +	res->irq = pci_irq_vector(pdev, 0);
> +
> +	return 0;
> +}
>
> Thus in case if for some reason you were able to allocate less MSI
> IRQs than required you'll still be able to use them. The legacy IRQ
> will be also available in case if MSI failed to be allocated.

Great, we will consider doing this in the future, but at this stage, we 
don't want to add too much complexity.


Thanks,

Yanteng
Yanteng Si April 3, 2024, 8:23 a.m. UTC | #7
在 2024/3/19 23:53, Serge Semin 写道:
> Then those platforms will_require_  to have the DT-node specified. This
> will define the DT-bindings which I doubt you imply here. Am I wrong?

yes,dt-node has specified irq information,and this driver also work with ACPI
configuration.

Thanks,
Yanteng
Serge Semin April 3, 2024, 12:03 p.m. UTC | #8
On Wed, Apr 03, 2024 at 04:09:21PM +0800, Yanteng Si wrote:
> 
> 在 2024/3/23 02:47, Serge Semin 写道:
> > +static int loongson_dwmac_config_multi_msi(struct pci_dev *pdev,
> > +					   struct plat_stmmacenet_data *plat,
> > +					   struct stmmac_resources *res)
> > +{
> > +	int i, ret, vecs;
> > +
> > +	/* INT NAME | MAC | CH7 rx | CH7 tx | ... | CH0 rx | CH0 tx |
> > +	 * --------- ----- -------- --------  ...  -------- --------
> > +	 * IRQ NUM  |  0  |   1    |   2    | ... |   15   |   16   |
> > +	 */
> > +	vecs = plat->rx_queues_to_use + plat->tx_queues_to_use + 1;
> > +	ret = pci_alloc_irq_vectors(pdev, 1, vecs, PCI_IRQ_MSI | PCI_IRQ_LEGACY);
> > +	if (ret < 0) {
> > +		dev_err(&pdev->dev, "Failed to allocate PCI IRQs\n");
> > +		return ret;
> > +	} else if (ret >= vecs) {
> > +		for (i = 0; i < plat->rx_queues_to_use; i++) {
> > +			res->rx_irq[CHANNELS_NUM - 1 - i] =
> > +				pci_irq_vector(pdev, 1 + i * 2);
> > +		}
> > +		for (i = 0; i < plat->tx_queues_to_use; i++) {
> > +			res->tx_irq[CHANNELS_NUM - 1 - i] =
> > +				pci_irq_vector(pdev, 2 + i * 2);
> > +		}
> > +
> > +		plat->flags |= STMMAC_FLAG_MULTI_MSI_EN;
> > +	}
> > +
> > +	res->irq = pci_irq_vector(pdev, 0);
> > +
> > +	return 0;
> > +}
> > 
> > Thus in case if for some reason you were able to allocate less MSI
> > IRQs than required you'll still be able to use them. The legacy IRQ
> > will be also available in case if MSI failed to be allocated.
> 
> Great, we will consider doing this in the future, but at this stage, we
> don't want to add too much complexity.

This comment isn't about complexity. Moreover the code in my comment
is simpler since the function is more coherent and doesn't have the
redundant dependencies from the node-pointer and the
loongson_dwmac_config_legacy() function. In addition it provides more
flexible solution in case if there were less MSI vectors allocated
then required.

-Serge(y)

> 
> 
> Thanks,
> 
> Yanteng
>
Yanteng Si April 5, 2024, 10:17 a.m. UTC | #9
在 2024/4/3 20:03, Serge Semin 写道:
> On Wed, Apr 03, 2024 at 04:09:21PM +0800, Yanteng Si wrote:
>> 在 2024/3/23 02:47, Serge Semin 写道:
>>> +static int loongson_dwmac_config_multi_msi(struct pci_dev *pdev,
>>> +					   struct plat_stmmacenet_data *plat,
>>> +					   struct stmmac_resources *res)
>>> +{
>>> +	int i, ret, vecs;
>>> +
>>> +	/* INT NAME | MAC | CH7 rx | CH7 tx | ... | CH0 rx | CH0 tx |
>>> +	 * --------- ----- -------- --------  ...  -------- --------
>>> +	 * IRQ NUM  |  0  |   1    |   2    | ... |   15   |   16   |
>>> +	 */
>>> +	vecs = plat->rx_queues_to_use + plat->tx_queues_to_use + 1;
>>> +	ret = pci_alloc_irq_vectors(pdev, 1, vecs, PCI_IRQ_MSI | PCI_IRQ_LEGACY);
>>> +	if (ret < 0) {
>>> +		dev_err(&pdev->dev, "Failed to allocate PCI IRQs\n");
>>> +		return ret;
>>> +	} else if (ret >= vecs) {
>>> +		for (i = 0; i < plat->rx_queues_to_use; i++) {
>>> +			res->rx_irq[CHANNELS_NUM - 1 - i] =
>>> +				pci_irq_vector(pdev, 1 + i * 2);
>>> +		}
>>> +		for (i = 0; i < plat->tx_queues_to_use; i++) {
>>> +			res->tx_irq[CHANNELS_NUM - 1 - i] =
>>> +				pci_irq_vector(pdev, 2 + i * 2);
>>> +		}
>>> +
>>> +		plat->flags |= STMMAC_FLAG_MULTI_MSI_EN;
>>> +	}
>>> +
>>> +	res->irq = pci_irq_vector(pdev, 0);
>>> +
>>> +	return 0;
>>> +}
>>>
>>> Thus in case if for some reason you were able to allocate less MSI
>>> IRQs than required you'll still be able to use them. The legacy IRQ
>>> will be also available in case if MSI failed to be allocated.
>> Great, we will consider doing this in the future, but at this stage, we
>> don't want to add too much complexity.
> This comment isn't about complexity. Moreover the code in my comment
> is simpler since the function is more coherent and doesn't have the
> redundant dependencies from the node-pointer and the
> loongson_dwmac_config_legacy() function. In addition it provides more
> flexible solution in case if there were less MSI vectors allocated
> then required.

I just tried it, the network card doesn't work, the reason is not clear.

Considering that the overall change is a little big, I want to send the 
current

working state as the patch v9.


However, I will continue to analyze the reasons for the failure and 
submit them

as a separate patch in the future. Is that OK?


Thanks,

Yanteng
diff mbox series

Patch

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
index 584f7322bd3e..60d0a122d7c9 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
@@ -98,10 +98,10 @@  static void dwlgmac_dma_init_channel(struct stmmac_priv *priv,
 	if (dma_cfg->aal)
 		value |= DMA_BUS_MODE_AAL;
 
-	writel(value, ioaddr + DMA_BUS_MODE);
+	writel(value, ioaddr + DMA_CHAN_BUS_MODE(chan));
 
 	/* Mask interrupts by writing to CSR7 */
-	writel(DMA_INTR_DEFAULT_MASK_LOONGSON, ioaddr + DMA_INTR_ENA);
+	writel(DMA_INTR_DEFAULT_MASK_LOONGSON, ioaddr + DMA_CHAN_INTR_ENA(chan));
 }
 
 static int dwlgmac_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr,
@@ -238,6 +238,45 @@  static int loongson_dwmac_config_legacy(struct pci_dev *pdev,
 	return 0;
 }
 
+static int loongson_dwmac_config_multi_msi(struct pci_dev *pdev,
+					   struct plat_stmmacenet_data *plat,
+					   struct stmmac_resources *res,
+					   struct device_node *np,
+					   int channel_num)
+{
+	int i, ret, vecs;
+
+	vecs = roundup_pow_of_two(channel_num * 2 + 1);
+	ret = pci_alloc_irq_vectors(pdev, vecs, vecs, PCI_IRQ_MSI);
+	if (ret < 0) {
+		dev_info(&pdev->dev,
+			 "MSI enable failed, Fallback to legacy interrupt\n");
+		return loongson_dwmac_config_legacy(pdev, plat, res, np);
+	}
+
+	plat->rx_queues_to_use = channel_num;
+	plat->tx_queues_to_use = channel_num;
+
+	res->irq = pci_irq_vector(pdev, 0);
+	res->wol_irq = res->irq;
+
+	/* INT NAME | MAC | CH7 rx | CH7 tx | ... | CH0 rx | CH0 tx |
+	 * --------- ----- -------- --------  ...  -------- --------
+	 * IRQ NUM  |  0  |   1    |   2    | ... |   15   |   16   |
+	 */
+	for (i = 0; i < channel_num; i++) {
+		res->rx_irq[channel_num - 1 - i] =
+			pci_irq_vector(pdev, 1 + i * 2);
+		res->tx_irq[channel_num - 1 - i] =
+			pci_irq_vector(pdev, 2 + i * 2);
+	}
+
+	plat->flags |= STMMAC_FLAG_MULTI_MSI_EN;
+	dev_info(&pdev->dev, "%s: multi MSI enablement successful\n", __func__);
+
+	return 0;
+}
+
 static void loongson_default_data(struct pci_dev *pdev,
 				  struct plat_stmmacenet_data *plat)
 {
@@ -296,11 +335,8 @@  static int loongson_gmac_config(struct pci_dev *pdev,
 				struct stmmac_resources *res,
 				struct device_node *np)
 {
-	int ret;
-
-	ret = loongson_dwmac_config_legacy(pdev, plat, res, np);
 
-	return ret;
+	return 0;
 }
 
 static struct stmmac_pci_info loongson_gmac_pci_info = {
@@ -380,11 +416,7 @@  static int loongson_gnet_config(struct pci_dev *pdev,
 				struct stmmac_resources *res,
 				struct device_node *np)
 {
-	int ret;
-
-	ret = loongson_dwmac_config_legacy(pdev, plat, res, np);
-
-	return ret;
+	return 0;
 }
 
 static struct stmmac_pci_info loongson_gnet_pci_info = {
@@ -483,6 +515,9 @@  static int loongson_dwmac_probe(struct pci_dev *pdev,
 		ld->dwlgmac_dma_ops.dma_interrupt = dwlgmac_dma_interrupt;
 
 		plat->setup = loongson_setup;
+		ret = loongson_dwmac_config_multi_msi(pdev, plat, &res, np, 8);
+	} else {
+		ret = loongson_dwmac_config_legacy(pdev, plat, &res, np);
 	}
 
 	plat->bsp_priv = ld;