All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
To: Andrew Lunn <andrew@lunn.ch>
Cc: "davem@davemloft.net" <davem@davemloft.net>,
	"edumazet@google.com" <edumazet@google.com>,
	"kuba@kernel.org" <kuba@kernel.org>,
	"pabeni@redhat.com" <pabeni@redhat.com>,
	"robh+dt@kernel.org" <robh+dt@kernel.org>,
	"krzysztof.kozlowski+dt@linaro.org" 
	<krzysztof.kozlowski+dt@linaro.org>,
	"netdev@vger.kernel.org" <netdev@vger.kernel.org>,
	"devicetree@vger.kernel.org" <devicetree@vger.kernel.org>,
	"linux-renesas-soc@vger.kernel.org" 
	<linux-renesas-soc@vger.kernel.org>
Subject: RE: [PATCH v3 2/3] net: ethernet: renesas: Add Ethernet Switch driver
Date: Mon, 26 Sep 2022 08:12:14 +0000	[thread overview]
Message-ID: <TYBPR01MB5341ACAD30E913D01C94FE08D8529@TYBPR01MB5341.jpnprd01.prod.outlook.com> (raw)
In-Reply-To: <Yy2wivbzUA2zroqy@lunn.ch>

Hi Andrew,

> From: Andrew Lunn, Sent: Friday, September 23, 2022 10:12 PM
> 
> > +/* Forwarding engine block (MFWD) */
> > +static void rswitch_fwd_init(struct rswitch_private *priv)
> > +{
> > +	int i;
> > +
> > +	for (i = 0; i < RSWITCH_NUM_HW; i++) {
> > +		iowrite32(FWPC0_DEFAULT, priv->addr + FWPC0(i));
> > +		iowrite32(0, priv->addr + FWPBFC(i));
> > +	}
> 
> What is RSWITCH_NUM_HW?

I think the name is unclear...
Anyway, this hardware has 3 ethernet ports and 2 CPU ports.
So that the RSWITCH_NUM_HW is 5. Perhaps, RSWITCH_NUM_ALL_PORTS
is better name.

Perhaps, since the current driver supports 1 ethernet port and 1 CPU port only,
I should modify this driver for the current condition strictly.

> > +
> > +	for (i = 0; i < RSWITCH_NUM_ETHA; i++) {
> 
> RSWITCH_NUM_ETHA appears to be the number of ports?

Yes, this is number of ethernet ports.

> > +static void rswitch_gwca_set_rate_limit(struct rswitch_private *priv, int rate)
> > +{
> > +	u32 gwgrlulc, gwgrlc;
> > +
> > +	switch (rate) {
> > +	case 1000:
> > +		gwgrlulc = 0x0000005f;
> > +		gwgrlc = 0x00010260;
> > +		break;
> > +	default:
> > +		dev_err(&priv->pdev->dev, "%s: This rate is not supported (%d)\n", __func__, rate);
> > +		return;
> > +	}
> 
> Is this setting the Mbps between the switch matrix and the CPU? Why
> limit the rate? Especially if you have 3 ports, would not 3000 make
> sense?

This is needed to avoid about 10% packets loss when the hardware sends data
because the hardware will send much data if the limit is not set.

> > +static void rswitch_get_data_irq_status(struct rswitch_private *priv, u32 *dis)
> > +{
> > +	int i;
> > +
> > +	for (i = 0; i < RSWITCH_NUM_IRQ_REGS; i++) {
> > +		dis[i] = ioread32(priv->addr + GWDIS(i));
> > +		dis[i] &= ioread32(priv->addr + GWDIE(i));
> > +	}
> > +}
> > +
> > +static void rswitch_enadis_data_irq(struct rswitch_private *priv, int index, bool enable)
> > +{
> > +	u32 offs = enable ? GWDIE(index / 32) : GWDID(index / 32);
> > +
> > +	iowrite32(BIT(index % 32), priv->addr + offs);
> > +}
> > +
> > +static void rswitch_ack_data_irq(struct rswitch_private *priv, int index)
> > +{
> > +	u32 offs = GWDIS(index / 32);
> > +
> > +	iowrite32(BIT(index % 32), priv->addr + offs);
> > +}
> > +
> > +static bool rswitch_is_chain_rxed(struct rswitch_gwca_chain *c)
> > +{
> > +	struct rswitch_ext_ts_desc *desc;
> > +	int entry;
> > +
> > +	entry = c->dirty % c->num_ring;
> > +	desc = &c->ts_ring[entry];
> > +
> > +	if ((desc->die_dt & DT_MASK) != DT_FEMPTY)
> > +		return true;
> > +
> > +	return false;
> 
> Is a chain a queue? Also known as a ring?

Yes.

> The naming is different to
> most drivers, which is making this harder to understand. Ideally, you
> want to follow the basic naming the majority of other drivers use.

I got it. I'll rename them.
 
> > +}
> > +
> > +static int rswitch_gwca_chain_alloc_skb(struct rswitch_gwca_chain *c,
> > +					int start, int num)
> > +{
> > +	int i, index;
> > +
> > +	for (i = start; i < (start + num); i++) {
> > +		index = i % c->num_ring;
> 
> Why this? Would it not make more sense to validate that start + num <
> num_ring? It seems like bad parameters passed here could destroy some
> other skb in the ring?

The descriptor indexes (c->cur and c->dirty) are just counters so that
the index is always calculated by that. This implementation is similar
with other drivers/net/ethernet/renesas/ drivers. However, as you mentioned
above, this is not majority, I think...

Also, I realized that the function will cause an issue because the types of
c->cur and c->dirty are u32, but the type of start is int.

I'll fix the indexes handling.

> More naming... Here you use num_ring, not num_chain. Try to be
> consistent. Also, num_ring makes my think of ring 7 of 9 rings. When
> this actually appears to be the size of the ring. So c->ring_size
> would be a better name.

Yes, the num_ring means the size of the ring. So, I'll rename it as your suggestion.

> > +		if (c->skb[index])
> > +			continue;
> > +		c->skb[index] = dev_alloc_skb(PKT_BUF_SZ + RSWITCH_ALIGN - 1);
> > +		if (!c->skb[index])
> > +			goto err;
> > +		skb_reserve(c->skb[index], NET_IP_ALIGN);
> 
> netdev_alloc_skb_ip_align()?

Yes. I'll use it. Thanks!

> > +static void rswitch_gwca_chain_free(struct net_device *ndev,
> > +				    struct rswitch_gwca_chain *c)
> > +{
> > +	int i;
> > +
> > +	if (c->gptp) {
> > +		dma_free_coherent(ndev->dev.parent,
> > +				  sizeof(struct rswitch_ext_ts_desc) *
> > +				  (c->num_ring + 1), c->ts_ring, c->ring_dma);
> > +		c->ts_ring = NULL;
> > +	} else {
> > +		dma_free_coherent(ndev->dev.parent,
> > +				  sizeof(struct rswitch_ext_desc) *
> > +				  (c->num_ring + 1), c->ring, c->ring_dma);
> > +		c->ring = NULL;
> > +	}
> > +
> > +	if (!c->dir_tx) {
> > +		for (i = 0; i < c->num_ring; i++)
> > +			dev_kfree_skb(c->skb[i]);
> > +	}
> > +
> > +	kfree(c->skb);
> > +	c->skb = NULL;
> 
> When i see code like this, i wonder why an API call like
> dev_kfree_skb() is not being used. I would suggest reaming this to
> something other than skb, which has a very well understood meaning.

Perhaps, c->skbs is better name than just c->skb.

> > +static bool rswitch_rx(struct net_device *ndev, int *quota)
> > +{
> > +	struct rswitch_device *rdev = netdev_priv(ndev);
> > +	struct rswitch_gwca_chain *c = rdev->rx_chain;
> > +	int entry = c->cur % c->num_ring;
> > +	struct rswitch_ext_ts_desc *desc;
> > +	int limit, boguscnt, num, ret;
> > +	struct sk_buff *skb;
> > +	dma_addr_t dma_addr;
> > +	u16 pkt_len;
> > +
> > +	boguscnt = min_t(int, c->dirty + c->num_ring - c->cur, *quota);
> > +	limit = boguscnt;
> > +
> > +	desc = &c->ts_ring[entry];
> > +	while ((desc->die_dt & DT_MASK) != DT_FEMPTY) {
> > +		dma_rmb();
> > +		pkt_len = le16_to_cpu(desc->info_ds) & RX_DS;
> > +		if (--boguscnt < 0)
> > +			break;
> 
> Why the barrier, read the length and then decide to break out of the
> loop?

Thank you for pointed it out. I should decrement/check boguscnt
before the barrier and read the length.

> > +static int rswitch_open(struct net_device *ndev)
> > +{
> > +	struct rswitch_device *rdev = netdev_priv(ndev);
> > +	struct device_node *phy;
> > +	int err = 0;
> > +
> > +	if (rdev->etha) {
> 
> Can this happen? What would a netdev without an etha mean?

This cannot happen now. So, I'll drop it.
(I intended to create a netdev without an etha as a virtual device.
 But the current driver doesn't have such a feature.)

Best regards,
Yoshihiro Shimoda

>     Andrew

  reply	other threads:[~2022-09-26  8:12 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-22  5:28 [PATCH v3 0/3] net: ethernet: renesas: Add Ethernet Switch driver Yoshihiro Shimoda
2022-09-22  5:28 ` [PATCH v3 1/3] dt-bindings: net: renesas: Document Renesas Ethernet Switch Yoshihiro Shimoda
2022-09-22  7:39   ` Krzysztof Kozlowski
2022-09-22  5:28 ` [PATCH v3 2/3] net: ethernet: renesas: Add Ethernet Switch driver Yoshihiro Shimoda
2022-09-23  2:43   ` Jakub Kicinski
2022-09-26  6:30     ` Yoshihiro Shimoda
2022-09-23 13:11   ` Andrew Lunn
2022-09-26  8:12     ` Yoshihiro Shimoda [this message]
2022-09-26 19:17       ` Andrew Lunn
2022-09-27  5:59         ` Yoshihiro Shimoda
2022-09-27 12:54           ` Andrew Lunn
2022-09-28  5:53             ` Yoshihiro Shimoda
2022-09-28 12:01               ` Andrew Lunn
2022-09-29 12:22                 ` Yoshihiro Shimoda
2022-09-29 15:00                   ` Andrew Lunn
2022-09-30 13:45                     ` Yoshihiro Shimoda
2022-09-22  5:28 ` [PATCH v3 3/3] net: ethernet: renesas: rswitch: Add R-Car Gen4 gPTP support Yoshihiro Shimoda

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=TYBPR01MB5341ACAD30E913D01C94FE08D8529@TYBPR01MB5341.jpnprd01.prod.outlook.com \
    --to=yoshihiro.shimoda.uh@renesas.com \
    --cc=andrew@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=devicetree@vger.kernel.org \
    --cc=edumazet@google.com \
    --cc=krzysztof.kozlowski+dt@linaro.org \
    --cc=kuba@kernel.org \
    --cc=linux-renesas-soc@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=robh+dt@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.