From: Herve Codina <herve.codina@bootlin.com>
To: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Andrew Lunn <andrew@lunn.ch>,
Vadim Fedorenko <vadim.fedorenko@linux.dev>,
Yury Norov <yury.norov@gmail.com>,
netdev@vger.kernel.org,
Rasmus Villemoes <linux@rasmusvillemoes.dk>,
linux-kernel@vger.kernel.org, Eric Dumazet <edumazet@google.com>,
Mark Brown <broonie@kernel.org>,
Thomas Petazzoni <thomas.petazzoni@bootlin.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
linuxppc-dev@lists.ozlabs.org,
"David S. Miller" <davem@davemloft.net>
Subject: Re: [PATCH v4 1/5] net: wan: Add support for QMC HDLC
Date: Thu, 22 Feb 2024 17:45:01 +0100 [thread overview]
Message-ID: <20240222174501.4cbe03ab@bootlin.com> (raw)
In-Reply-To: <ZddoQTg32unJJ_qP@smile.fi.intel.com>
On Thu, 22 Feb 2024 17:29:05 +0200
Andy Shevchenko <andriy.shevchenko@linux.intel.com> wrote:
> On Thu, Feb 22, 2024 at 03:22:14PM +0100, Herve Codina wrote:
> > The QMC HDLC driver provides support for HDLC using the QMC (QUICC
> > Multichannel Controller) to transfer the HDLC data.
>
> ...
>
> > +struct qmc_hdlc {
> > + struct device *dev;
> > + struct qmc_chan *qmc_chan;
> > + struct net_device *netdev;
> > + bool is_crc32;
> > + spinlock_t tx_lock; /* Protect tx descriptors */
>
> Just wondering if above tx/rx descriptors should be aligned on a cacheline
> for DMA?
These descriptors are not used by DMA.
Not sure that aligning them to a cacheline is really needed.
>
> > + struct qmc_hdlc_desc tx_descs[8];
> > + unsigned int tx_out;
> > + struct qmc_hdlc_desc rx_descs[4];
> > +};
>
> ...
>
> > +#define QMC_HDLC_RX_ERROR_FLAGS (QMC_RX_FLAG_HDLC_OVF | \
> > + QMC_RX_FLAG_HDLC_UNA | \
> > + QMC_RX_FLAG_HDLC_ABORT | \
> > + QMC_RX_FLAG_HDLC_CRC)
>
> Wouldn't be slightly better to have it as
>
> #define QMC_HDLC_RX_ERROR_FLAGS \
> (QMC_RX_FLAG_HDLC_OVF | QMC_RX_FLAG_HDLC_UNA | \
> QMC_RX_FLAG_HDLC_CRC | QMC_RX_FLAG_HDLC_ABORT)
>
> ?
Will be done in the next iteration.
>
> ...
>
> > + ret = qmc_chan_write_submit(qmc_hdlc->qmc_chan, desc->dma_addr, desc->dma_size,
> > + qmc_hdlc_xmit_complete, desc);
> > + if (ret) {
>
> > + dev_err(qmc_hdlc->dev, "qmc chan write returns %d\n", ret);
> > + dma_unmap_single(qmc_hdlc->dev, desc->dma_addr, desc->dma_size, DMA_TO_DEVICE);
> > + return ret;
>
> I would do other way around, i.e. release resource followed up by printing
> a message. Printing a message is a slow operation and may prevent the (soon
> freed) resources to be re-used earlier.
Will do that in the next iteration.
>
> > + }
>
> ...
>
> > + spin_lock_irqsave(&qmc_hdlc->tx_lock, flags);
>
> Why not using cleanup.h from day 1?
I don't know about cleanup.h.
Can you tell me more ?
How should I use it ?
>
> > +end:
>
> This label, in particular, will not be needed with above in place.
>
> > + spin_unlock_irqrestore(&qmc_hdlc->tx_lock, flags);
> > + return ret;
> > +}
>
> ...
>
> > + /* Queue as many recv descriptors as possible */
> > + for (i = 0; i < ARRAY_SIZE(qmc_hdlc->rx_descs); i++) {
> > + desc = &qmc_hdlc->rx_descs[i];
> > +
> > + desc->netdev = netdev;
> > + ret = qmc_hdlc_recv_queue(qmc_hdlc, desc, chan_param.hdlc.max_rx_buf_size);
>
> > + if (ret) {
> > + if (ret == -EBUSY && i != 0)
> > + break; /* We use all the QMC chan capability */
> > + goto free_desc;
> > + }
>
> Can be unfolded to
>
> if (ret == -EBUSY && i)
> break; /* We use all the QMC chan capability */
> if (ret)
> goto free_desc;
>
> Easy to read and understand.
Sure, will be changed.
>
> > + }
>
> ...
>
> > +static int qmc_hdlc_probe(struct platform_device *pdev)
> > +{
>
> With
>
> struct device *dev = &pdev->dev;
>
> the below code will be neater (see other comments for the examples).
Will use that.
>
> > + struct device_node *np = pdev->dev.of_node;
>
> It is used only once, drop it (see below).
Ok.
>
> > + struct qmc_hdlc *qmc_hdlc;
> > + struct qmc_chan_info info;
> > + hdlc_device *hdlc;
> > + int ret;
> > +
> > + qmc_hdlc = devm_kzalloc(&pdev->dev, sizeof(*qmc_hdlc), GFP_KERNEL);
> > + if (!qmc_hdlc)
> > + return -ENOMEM;
> > +
> > + qmc_hdlc->dev = &pdev->dev;
> > + spin_lock_init(&qmc_hdlc->tx_lock);
> > +
> > + qmc_hdlc->qmc_chan = devm_qmc_chan_get_bychild(qmc_hdlc->dev, np);
>
> qmc_hdlc->qmc_chan = devm_qmc_chan_get_bychild(dev, dev->of_node);
>
> > + if (IS_ERR(qmc_hdlc->qmc_chan)) {
> > + ret = PTR_ERR(qmc_hdlc->qmc_chan);
> > + return dev_err_probe(qmc_hdlc->dev, ret, "get QMC channel failed\n");
>
> return dev_err_probe(dev, PTR_ERR(qmc_hdlc->qmc_chan), "get QMC channel failed\n");
>
> > + }
> > +
> > + ret = qmc_chan_get_info(qmc_hdlc->qmc_chan, &info);
> > + if (ret) {
>
> > + dev_err(qmc_hdlc->dev, "get QMC channel info failed %d\n", ret);
> > + return ret;
>
> Why not using same message pattern everywhere, i.e. dev_err_probe()?
>
> return dev_err_probe(dev, ret, "get QMC channel info failed\n");
>
> (and so on...)
No reason. Just because I missed them.
Will be updated using dev_err_probe().
>
> > + }
> > +
> > + if (info.mode != QMC_HDLC) {
> > + dev_err(qmc_hdlc->dev, "QMC chan mode %d is not QMC_HDLC\n",
> > + info.mode);
> > + return -EINVAL;
> > + }
> > +
> > + qmc_hdlc->netdev = alloc_hdlcdev(qmc_hdlc);
> > + if (!qmc_hdlc->netdev) {
>
> > + dev_err(qmc_hdlc->dev, "failed to alloc hdlc dev\n");
> > + return -ENOMEM;
>
> We do not issue a message for -ENOMEM.
And I know :(
Will be updated.
>
> > + }
> > +
> > + hdlc = dev_to_hdlc(qmc_hdlc->netdev);
> > + hdlc->attach = qmc_hdlc_attach;
> > + hdlc->xmit = qmc_hdlc_xmit;
> > + SET_NETDEV_DEV(qmc_hdlc->netdev, qmc_hdlc->dev);
> > + qmc_hdlc->netdev->tx_queue_len = ARRAY_SIZE(qmc_hdlc->tx_descs);
> > + qmc_hdlc->netdev->netdev_ops = &qmc_hdlc_netdev_ops;
> > + ret = register_hdlc_device(qmc_hdlc->netdev);
> > + if (ret) {
> > + dev_err(qmc_hdlc->dev, "failed to register hdlc device (%d)\n", ret);
> > + goto free_netdev;
> > + }
> > +
> > + platform_set_drvdata(pdev, qmc_hdlc);
> > +
> > + return 0;
> > +
> > +free_netdev:
> > + free_netdev(qmc_hdlc->netdev);
> > + return ret;
> > +}
>
>
Thanks for the review.
Hervé
WARNING: multiple messages have this Message-ID (diff)
From: Herve Codina <herve.codina@bootlin.com>
To: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Vadim Fedorenko <vadim.fedorenko@linux.dev>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Yury Norov <yury.norov@gmail.com>,
Rasmus Villemoes <linux@rasmusvillemoes.dk>,
linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
linuxppc-dev@lists.ozlabs.org, Andrew Lunn <andrew@lunn.ch>,
Mark Brown <broonie@kernel.org>,
Christophe Leroy <christophe.leroy@csgroup.eu>,
Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Subject: Re: [PATCH v4 1/5] net: wan: Add support for QMC HDLC
Date: Thu, 22 Feb 2024 17:45:01 +0100 [thread overview]
Message-ID: <20240222174501.4cbe03ab@bootlin.com> (raw)
In-Reply-To: <ZddoQTg32unJJ_qP@smile.fi.intel.com>
On Thu, 22 Feb 2024 17:29:05 +0200
Andy Shevchenko <andriy.shevchenko@linux.intel.com> wrote:
> On Thu, Feb 22, 2024 at 03:22:14PM +0100, Herve Codina wrote:
> > The QMC HDLC driver provides support for HDLC using the QMC (QUICC
> > Multichannel Controller) to transfer the HDLC data.
>
> ...
>
> > +struct qmc_hdlc {
> > + struct device *dev;
> > + struct qmc_chan *qmc_chan;
> > + struct net_device *netdev;
> > + bool is_crc32;
> > + spinlock_t tx_lock; /* Protect tx descriptors */
>
> Just wondering if above tx/rx descriptors should be aligned on a cacheline
> for DMA?
These descriptors are not used by DMA.
Not sure that aligning them to a cacheline is really needed.
>
> > + struct qmc_hdlc_desc tx_descs[8];
> > + unsigned int tx_out;
> > + struct qmc_hdlc_desc rx_descs[4];
> > +};
>
> ...
>
> > +#define QMC_HDLC_RX_ERROR_FLAGS (QMC_RX_FLAG_HDLC_OVF | \
> > + QMC_RX_FLAG_HDLC_UNA | \
> > + QMC_RX_FLAG_HDLC_ABORT | \
> > + QMC_RX_FLAG_HDLC_CRC)
>
> Wouldn't be slightly better to have it as
>
> #define QMC_HDLC_RX_ERROR_FLAGS \
> (QMC_RX_FLAG_HDLC_OVF | QMC_RX_FLAG_HDLC_UNA | \
> QMC_RX_FLAG_HDLC_CRC | QMC_RX_FLAG_HDLC_ABORT)
>
> ?
Will be done in the next iteration.
>
> ...
>
> > + ret = qmc_chan_write_submit(qmc_hdlc->qmc_chan, desc->dma_addr, desc->dma_size,
> > + qmc_hdlc_xmit_complete, desc);
> > + if (ret) {
>
> > + dev_err(qmc_hdlc->dev, "qmc chan write returns %d\n", ret);
> > + dma_unmap_single(qmc_hdlc->dev, desc->dma_addr, desc->dma_size, DMA_TO_DEVICE);
> > + return ret;
>
> I would do other way around, i.e. release resource followed up by printing
> a message. Printing a message is a slow operation and may prevent the (soon
> freed) resources to be re-used earlier.
Will do that in the next iteration.
>
> > + }
>
> ...
>
> > + spin_lock_irqsave(&qmc_hdlc->tx_lock, flags);
>
> Why not using cleanup.h from day 1?
I don't know about cleanup.h.
Can you tell me more ?
How should I use it ?
>
> > +end:
>
> This label, in particular, will not be needed with above in place.
>
> > + spin_unlock_irqrestore(&qmc_hdlc->tx_lock, flags);
> > + return ret;
> > +}
>
> ...
>
> > + /* Queue as many recv descriptors as possible */
> > + for (i = 0; i < ARRAY_SIZE(qmc_hdlc->rx_descs); i++) {
> > + desc = &qmc_hdlc->rx_descs[i];
> > +
> > + desc->netdev = netdev;
> > + ret = qmc_hdlc_recv_queue(qmc_hdlc, desc, chan_param.hdlc.max_rx_buf_size);
>
> > + if (ret) {
> > + if (ret == -EBUSY && i != 0)
> > + break; /* We use all the QMC chan capability */
> > + goto free_desc;
> > + }
>
> Can be unfolded to
>
> if (ret == -EBUSY && i)
> break; /* We use all the QMC chan capability */
> if (ret)
> goto free_desc;
>
> Easy to read and understand.
Sure, will be changed.
>
> > + }
>
> ...
>
> > +static int qmc_hdlc_probe(struct platform_device *pdev)
> > +{
>
> With
>
> struct device *dev = &pdev->dev;
>
> the below code will be neater (see other comments for the examples).
Will use that.
>
> > + struct device_node *np = pdev->dev.of_node;
>
> It is used only once, drop it (see below).
Ok.
>
> > + struct qmc_hdlc *qmc_hdlc;
> > + struct qmc_chan_info info;
> > + hdlc_device *hdlc;
> > + int ret;
> > +
> > + qmc_hdlc = devm_kzalloc(&pdev->dev, sizeof(*qmc_hdlc), GFP_KERNEL);
> > + if (!qmc_hdlc)
> > + return -ENOMEM;
> > +
> > + qmc_hdlc->dev = &pdev->dev;
> > + spin_lock_init(&qmc_hdlc->tx_lock);
> > +
> > + qmc_hdlc->qmc_chan = devm_qmc_chan_get_bychild(qmc_hdlc->dev, np);
>
> qmc_hdlc->qmc_chan = devm_qmc_chan_get_bychild(dev, dev->of_node);
>
> > + if (IS_ERR(qmc_hdlc->qmc_chan)) {
> > + ret = PTR_ERR(qmc_hdlc->qmc_chan);
> > + return dev_err_probe(qmc_hdlc->dev, ret, "get QMC channel failed\n");
>
> return dev_err_probe(dev, PTR_ERR(qmc_hdlc->qmc_chan), "get QMC channel failed\n");
>
> > + }
> > +
> > + ret = qmc_chan_get_info(qmc_hdlc->qmc_chan, &info);
> > + if (ret) {
>
> > + dev_err(qmc_hdlc->dev, "get QMC channel info failed %d\n", ret);
> > + return ret;
>
> Why not using same message pattern everywhere, i.e. dev_err_probe()?
>
> return dev_err_probe(dev, ret, "get QMC channel info failed\n");
>
> (and so on...)
No reason. Just because I missed them.
Will be updated using dev_err_probe().
>
> > + }
> > +
> > + if (info.mode != QMC_HDLC) {
> > + dev_err(qmc_hdlc->dev, "QMC chan mode %d is not QMC_HDLC\n",
> > + info.mode);
> > + return -EINVAL;
> > + }
> > +
> > + qmc_hdlc->netdev = alloc_hdlcdev(qmc_hdlc);
> > + if (!qmc_hdlc->netdev) {
>
> > + dev_err(qmc_hdlc->dev, "failed to alloc hdlc dev\n");
> > + return -ENOMEM;
>
> We do not issue a message for -ENOMEM.
And I know :(
Will be updated.
>
> > + }
> > +
> > + hdlc = dev_to_hdlc(qmc_hdlc->netdev);
> > + hdlc->attach = qmc_hdlc_attach;
> > + hdlc->xmit = qmc_hdlc_xmit;
> > + SET_NETDEV_DEV(qmc_hdlc->netdev, qmc_hdlc->dev);
> > + qmc_hdlc->netdev->tx_queue_len = ARRAY_SIZE(qmc_hdlc->tx_descs);
> > + qmc_hdlc->netdev->netdev_ops = &qmc_hdlc_netdev_ops;
> > + ret = register_hdlc_device(qmc_hdlc->netdev);
> > + if (ret) {
> > + dev_err(qmc_hdlc->dev, "failed to register hdlc device (%d)\n", ret);
> > + goto free_netdev;
> > + }
> > +
> > + platform_set_drvdata(pdev, qmc_hdlc);
> > +
> > + return 0;
> > +
> > +free_netdev:
> > + free_netdev(qmc_hdlc->netdev);
> > + return ret;
> > +}
>
>
Thanks for the review.
Hervé
next prev parent reply other threads:[~2024-02-22 16:46 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-02-22 14:22 [PATCH v4 0/5] Add support for QMC HDLC Herve Codina
2024-02-22 14:22 ` Herve Codina
2024-02-22 14:22 ` [PATCH v4 1/5] net: wan: " Herve Codina
2024-02-22 14:22 ` Herve Codina
2024-02-22 15:29 ` Andy Shevchenko
2024-02-22 15:29 ` Andy Shevchenko
2024-02-22 16:45 ` Herve Codina [this message]
2024-02-22 16:45 ` Herve Codina
2024-02-22 16:56 ` Andy Shevchenko
2024-02-22 16:56 ` Andy Shevchenko
2024-02-22 17:45 ` Herve Codina
2024-02-22 17:45 ` Herve Codina
2024-02-22 14:22 ` [PATCH v4 2/5] MAINTAINERS: Add the Freescale QMC HDLC driver entry Herve Codina
2024-02-22 14:22 ` Herve Codina
2024-02-22 14:22 ` [PATCH v4 3/5] lib/bitmap: Introduce bitmap_scatter() and bitmap_gather() helpers Herve Codina
2024-02-22 14:22 ` Herve Codina
2024-02-22 15:39 ` Andy Shevchenko
2024-02-22 15:39 ` Andy Shevchenko
2024-02-22 15:40 ` Andy Shevchenko
2024-02-22 15:40 ` Andy Shevchenko
2024-02-22 16:49 ` Herve Codina
2024-02-22 16:49 ` Herve Codina
2024-02-22 21:50 ` Yury Norov
2024-02-22 21:50 ` Yury Norov
2024-02-23 10:07 ` Herve Codina
2024-02-23 10:07 ` Herve Codina
2024-02-22 14:22 ` [PATCH v4 4/5] net: wan: fsl_qmc_hdlc: Add runtime timeslots changes support Herve Codina
2024-02-22 14:22 ` Herve Codina
2024-02-22 15:47 ` Andy Shevchenko
2024-02-22 15:47 ` Andy Shevchenko
2024-02-23 16:46 ` Herve Codina
2024-02-23 16:46 ` Herve Codina
2024-02-22 14:22 ` [PATCH v4 5/5] net: wan: fsl_qmc_hdlc: Add framer support Herve Codina
2024-02-22 14:22 ` Herve Codina
2024-02-22 15:49 ` Andy Shevchenko
2024-02-22 15:49 ` Andy Shevchenko
2024-02-29 12:56 ` Herve Codina
2024-02-29 12:56 ` Herve Codina
2024-02-29 13:58 ` Andy Shevchenko
2024-02-29 13:58 ` Andy Shevchenko
2024-02-29 14:15 ` Herve Codina
2024-02-29 14:15 ` Herve Codina
2024-02-22 15:50 ` [PATCH v4 0/5] Add support for QMC HDLC Andy Shevchenko
2024-02-22 15:50 ` Andy Shevchenko
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=20240222174501.4cbe03ab@bootlin.com \
--to=herve.codina@bootlin.com \
--cc=andrew@lunn.ch \
--cc=andriy.shevchenko@linux.intel.com \
--cc=broonie@kernel.org \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@rasmusvillemoes.dk \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=thomas.petazzoni@bootlin.com \
--cc=vadim.fedorenko@linux.dev \
--cc=yury.norov@gmail.com \
/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.