netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Vadym Kochan <vadym.kochan@plvision.eu>
To: Andy Shevchenko <andy.shevchenko@gmail.com>
Cc: "David S. Miller" <davem@davemloft.net>,
	Jakub Kicinski <kuba@kernel.org>, Jiri Pirko <jiri@mellanox.com>,
	Ido Schimmel <idosch@mellanox.com>, Andrew Lunn <andrew@lunn.ch>,
	Oleksandr Mazur <oleksandr.mazur@plvision.eu>,
	Serhiy Boiko <serhiy.boiko@plvision.eu>,
	Serhiy Pshyk <serhiy.pshyk@plvision.eu>,
	Volodymyr Mytnyk <volodymyr.mytnyk@plvision.eu>,
	Taras Chornyi <taras.chornyi@plvision.eu>,
	Andrii Savka <andrii.savka@plvision.eu>,
	netdev <netdev@vger.kernel.org>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	Mickey Rachamim <mickeyr@marvell.com>
Subject: Re: [net-next v4 1/6] net: marvell: prestera: Add driver for Prestera family ASIC devices
Date: Fri, 31 Jul 2020 18:22:01 +0300	[thread overview]
Message-ID: <20200731152201.GB10391@plvision.eu> (raw)
In-Reply-To: <CAHp75Ve-MyFg5QqHjywGk6X+v_F77HkRBuQsJ0Cx3WLJ5ZV43w@mail.gmail.com>

Hi Andy,

On Mon, Jul 27, 2020 at 03:59:13PM +0300, Andy Shevchenko wrote:
> On Mon, Jul 27, 2020 at 3:23 PM Vadym Kochan <vadym.kochan@plvision.eu> wrote:
> >
> > Marvell Prestera 98DX326x integrates up to 24 ports of 1GbE with 8
> > ports of 10GbE uplinks or 2 ports of 40Gbps stacking for a largely
> > wireless SMB deployment.
> >
> > The current implementation supports only boards designed for the Marvell
> > Switchdev solution and requires special firmware.
> >
> > The core Prestera switching logic is implemented in prestera_main.c,
> > there is an intermediate hw layer between core logic and firmware. It is
> > implemented in prestera_hw.c, the purpose of it is to encapsulate hw
> > related logic, in future there is a plan to support more devices with
> > different HW related configurations.
> >
> > This patch contains only basic switch initialization and RX/TX support
> > over SDMA mechanism.
> >
> > Currently supported devices have DMA access range <= 32bit and require
> > ZONE_DMA to be enabled, for such cases SDMA driver checks if the skb
> > allocated in proper range supported by the Prestera device.
> >
> > Also meanwhile there is no TX interrupt support in current firmware
> > version so recycling work is scheduled on each xmit.
> >
> > Port's mac address is generated from the switch base mac which may be
> > provided via device-tree (static one or as nvme cell), or randomly
> > generated.
> 
> ...
> 
> > Signed-off-by: Andrii Savka <andrii.savka@plvision.eu>
> > Signed-off-by: Oleksandr Mazur <oleksandr.mazur@plvision.eu>
> > Signed-off-by: Serhiy Boiko <serhiy.boiko@plvision.eu>
> > Signed-off-by: Serhiy Pshyk <serhiy.pshyk@plvision.eu>
> > Signed-off-by: Taras Chornyi <taras.chornyi@plvision.eu>
> > Signed-off-by: Volodymyr Mytnyk <volodymyr.mytnyk@plvision.eu>
> > Signed-off-by: Vadym Kochan <vadym.kochan@plvision.eu>
> 
> This needs more work. You have to really understand the role of each
> person in the above list.
> I highly recommend (re-)read sections 11-13 of Submitting Patches.
> 
At least looks like I need to add these persons as Co-author's.

> ...
> 
> > +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
> 
> The idea of SPDX is to have it as a separate (standalone) comment.
OK, thanks.

> 
> ...
> 
> > +enum prestera_event_type {
> > +       PRESTERA_EVENT_TYPE_UNSPEC,
> > +
> > +       PRESTERA_EVENT_TYPE_PORT,
> > +       PRESTERA_EVENT_TYPE_RXTX,
> > +
> > +       PRESTERA_EVENT_TYPE_MAX,
> 
> Commas in the terminators are not good.
> 
OK

> > +};
> 
> ...
> 
> > +#include "prestera_dsa.h"
> 
> The idea that you include more generic headers earlier than more custom ones.
> 
Thanks

> > +#include <linux/string.h>
> > +#include <linux/bitops.h>
> > +#include <linux/bitfield.h>
> > +#include <linux/errno.h>
> 
> Perhaps ordered?
> 
alphabetical ?

> ...
> 
> > +/* TrgDev[4:0] = {Word0[28:24]} */
> 
> > + * SrcPort/TrgPort[7:0] = {Word2[20], Word1[11:10], Word0[23:19]}
> 
> > +/* bits 13:15 -- UP */
> 
> > +/* bits 0:11 -- VID */
> 
> These are examples of useless comments.
> 
OK, removed.

> ...
> 
> > +       dsa->vlan.is_tagged = (bool)FIELD_GET(PRESTERA_W0_IS_TAGGED, words[0]);
> > +       dsa->vlan.cfi_bit = (u8)FIELD_GET(PRESTERA_W1_CFI_BIT, words[1]);
> > +       dsa->vlan.vpt = (u8)FIELD_GET(PRESTERA_W0_VPT, words[0]);
> > +       dsa->vlan.vid = (u16)FIELD_GET(PRESTERA_W0_VID, words[0]);
> 
> Do you need those castings?
> 
Looks like not, because the struct fields are same type as cast'ed ones.

> ...
> 
> > +       struct prestera_msg_event_port *hw_evt;
> > +
> > +       hw_evt = (struct prestera_msg_event_port *)msg;
> 
> Can be one line I suppose.
> 
Yes, but I am trying to avoid line-breaking because of 80 chars
limitation.

> ...
> 
> > +       if (evt->id == PRESTERA_PORT_EVENT_STATE_CHANGED)
> > +               evt->port_evt.data.oper_state = hw_evt->param.oper_state;
> > +       else
> > +               return -EINVAL;
> > +
> > +       return 0;
> 
> Perhaps traditional pattern, i.e.
> 
>   if (...)
>     return -EINVAL;
>   ...
>   return 0;
> 
I am not sure if it is applicable here, because the error state here
is if 'evt->id' did not matched after all checks. Actually this is
simply a 'switch', but I use 'if' to have shorter code.

> ...
> 
> > +       err = fw_event_parsers[msg->type].func(buf, &evt);
> > +       if (!err)
> > +               eh.func(sw, &evt, eh.arg);
> 
> Ditto.
Makes sense.

> 
> > +       return err;
> 
> ...
> 
> > +       memcpy(&req.param.mac, mac, sizeof(req.param.mac));
> 
> Consider to use ether_addr_*() APIs instead of open-coded mem*() ones.
> 
> ...
> 
> > +#define PRESTERA_MTU_DEFAULT 1536
> 
> Don't we have global default for this?
> 
> ...
> 
> > +#define PRESTERA_STATS_DELAY_MS        msecs_to_jiffies(1000)
> 
> It's not _MS.
> 
> ...
> 
> > +       if (!is_up)
> > +               netif_stop_queue(dev);
> > +
> > +       err = prestera_hw_port_state_set(port, is_up);
> > +
> > +       if (is_up && !err)
> > +               netif_start_queue(dev);
> 
> Much better if will look lke
> 
>   if (is_up) {
>   ...
>   err  = ...(..., true);
>   if (err)
>     return err;
>   ...
>   } else {
>     return prestera_*(..., false);
>   }
>   return 0;
> 
> > +       return err;
> 
> ...
> 
> > +       /* Only 0xFF mac addrs are supported */
> > +       if (port->fp_id >= 0xFF)
> > +               goto err_port_init;
> 
> You meant 255, right?
> Otherwise you have to mentioned is it byte limitation or what?
> 
> ...
Yes, 255 is a limitation because of max byte value.

> 
> > +static int prestera_switch_set_base_mac_addr(struct prestera_switch *sw)
> > +{
> > +       struct device_node *base_mac_np;
> > +       struct device_node *np;
> 
> > +       np = of_find_compatible_node(NULL, NULL, "marvell,prestera");
> > +       if (np) {
> > +               base_mac_np = of_parse_phandle(np, "base-mac-provider", 0);
> > +               if (base_mac_np) {
> > +                       const char *base_mac;
> > +
> > +                       base_mac = of_get_mac_address(base_mac_np);
> > +                       of_node_put(base_mac_np);
> > +                       if (!IS_ERR(base_mac))
> > +                               ether_addr_copy(sw->base_mac, base_mac);
> > +               }
> > +       }
> > +
> > +       if (!is_valid_ether_addr(sw->base_mac)) {
> > +               eth_random_addr(sw->base_mac);
> > +               dev_info(sw->dev->dev, "using random base mac address\n");
> > +       }
> 
> Isn't it device_get_mac_address() reimplementation?
> 
device_get_mac_address() just tries to get mac via fwnode.

> > +
> > +       return prestera_hw_switch_mac_set(sw, sw->base_mac);
> > +}
> 
> ...
> 
> > +       err = prestera_switch_init(sw);
> > +       if (err) {
> > +               kfree(sw);
> > +               return err;
> > +       }
> > +
> > +       return 0;
> 
> if (err)
>  kfree(...);
> return err;
> 
> Also, check reference counting.
> 
> ...
> 
> > +#define PRESTERA_SDMA_RX_DESC_PKT_LEN(desc) \
> 
> > +       ((le32_to_cpu((desc)->word2) >> 16) & 0x3FFF)
> 
> Why not GENMASK() ?
Yes, GENMASK is right way to go, thanks.

> 
> ...
> 
> > +       if (dma + sizeof(struct prestera_sdma_desc) > sdma->dma_mask) {
> > +               dev_err(dma_dev, "failed to alloc desc\n");
> > +               dma_pool_free(sdma->desc_pool, desc, dma);
> 
> Better first undo something *then* print a message.
> 
> > +               return -ENOMEM;
> > +       }
> 
> ...
> 
> > +static void prestera_sdma_rx_desc_set_len(struct prestera_sdma_desc *desc,
> > +                                         size_t val)
> > +{
> > +       u32 word = le32_to_cpu(desc->word2);
> > +
> > +       word = (word & ~GENMASK(15, 0)) | val;
> 
> Shouldn't you do traditional pattern?
> 
> word = (word & ~mask) | (val & mask);
Looks like this is safer form.

> 
> > +       desc->word2 = cpu_to_le32(word);
> > +}
> 
> ...
> 
> > +       dma = dma_map_single(dev, skb->data, skb->len, DMA_FROM_DEVICE);
> 
> > +
> 
> Redundant blank line.
> 
> > +       if (dma_mapping_error(dev, dma))
> > +               goto err_dma_map;
> 
> ...
> 
> > +               pr_warn_ratelimited("received pkt for non-existent port(%u, %u)\n",
> > +                                   dev_id, hw_port);
> 
> netdev_warn_ratelimited() ? Or something closer to that?
> 
> ...
> 
> > +       qmask = GENMASK(qnum - 1, 0);
> 
> BIT(qnum) - 1 will produce much better code I suppose.
> 
> ...
> 
> > +       if (pkts_done < budget && napi_complete_done(napi, pkts_done))
> > +               prestera_write(sdma->sw, PRESTERA_SDMA_RX_INTR_MASK_REG,
> > +                              0xff << 2);
> 
> GENMASK() ?
> 
> ...
> 
> > +       word = (word & ~GENMASK(30, 16)) | ((len + ETH_FCS_LEN) << 16);
> 
> Consider traditional pattern.
> 
> ...
> 
> > +       word |= PRESTERA_SDMA_TX_DESC_DMA_OWN << 31;
> 
> I hope that was defined with U. Otherwise it's UB.
> 
> ...
> 
> > +       new_skb = alloc_skb(len, GFP_ATOMIC | GFP_DMA);
> 
> Atomic? Why?
> 
TX path might be called from net_tx_action which is softirq.

> ...
> 
> > +static int prestera_sdma_tx_wait(struct prestera_sdma *sdma,
> > +                                struct prestera_tx_ring *tx_ring)
> > +{
> 
> > +       int tx_retry_num = 10 * tx_ring->max_burst;
> 
> Magic!
You mean the code is magic ? Yes, I am trying to relax the
calling of SDMA engine.

> 
> > +       while (--tx_retry_num) {
> > +               if (prestera_sdma_is_ready(sdma))
> > +                       return 0;
> > +
> > +               udelay(1);
> > +       }
> 
> unsigned int counter = ...;
> 
> do { } while (--counter);
> 
> looks better.
> 
> Also, why udelay()? Is it atomic context?
TX path might be called from net_tx_action which is softirq.

> 
> > +       return -EBUSY;
> > +}
> 
> ...
> 
> > +       if (!tx_ring->burst--) {
> 
> Don't do like this. It makes code harder to understand.
> 
>   if (tx_ring->...) {
>     ...->burst--;
>   } else {
>     ...
>   }
I will try.

> 
> > +               tx_ring->burst = tx_ring->max_burst;
> > +
> > +               err = prestera_sdma_tx_wait(sdma, tx_ring);
> > +               if (err)
> > +                       goto drop_skb_unmap;
> > +       }
> 
> -- 
> With Best Regards,
> Andy Shevchenko

  reply	other threads:[~2020-07-31 15:22 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-27 12:22 [net-next v4 0/6] net: marvell: prestera: Add Switchdev driver for Prestera family ASIC device 98DX326x (AC3x) Vadym Kochan
2020-07-27 12:22 ` [net-next v4 1/6] net: marvell: prestera: Add driver for Prestera family ASIC devices Vadym Kochan
2020-07-27 12:59   ` Andy Shevchenko
2020-07-31 15:22     ` Vadym Kochan [this message]
2020-07-31 16:02       ` Andy Shevchenko
2020-07-31 20:55         ` Vadym Kochan
2020-07-27 19:32   ` David Miller
2020-08-13  8:03   ` Jonathan McDowell
2020-08-14  8:20     ` Vadym Kochan
2020-08-14 12:05       ` Jonathan McDowell
2020-08-14 12:27         ` Vadym Kochan
2020-08-14 13:18           ` Andrew Lunn
2020-08-20  8:31             ` Vadym Kochan
2020-08-20 10:00               ` [EXT] " Mickey Rachamim
2020-08-22 16:34                 ` Andrew Lunn
2020-08-25 11:36                   ` Vadym Kochan
2020-07-27 12:22 ` [net-next v4 2/6] net: marvell: prestera: Add PCI interface support Vadym Kochan
2020-07-27 12:32   ` Jiri Pirko
2020-07-27 12:35     ` Vadym Kochan
2020-07-27 13:02       ` Jiri Pirko
2020-07-27 13:29   ` Andy Shevchenko
2020-07-27 14:11     ` Jiri Pirko
2020-07-27 15:33       ` Andy Shevchenko
2020-07-27 12:22 ` [net-next v4 3/6] net: marvell: prestera: Add basic devlink support Vadym Kochan
2020-07-27 13:07   ` Andy Shevchenko
2020-07-28 12:30     ` Vadym Kochan
2020-07-28 13:24       ` Andy Shevchenko
2020-07-27 12:22 ` [net-next v4 4/6] net: marvell: prestera: Add ethtool interface support Vadym Kochan
2020-07-27 13:17   ` Andy Shevchenko
2020-07-27 12:22 ` [net-next v4 5/6] net: marvell: prestera: Add Switchdev driver implementation Vadym Kochan
2020-07-27 12:22 ` [net-next v4 6/6] dt-bindings: marvell,prestera: Add description for device-tree bindings Vadym Kochan

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=20200731152201.GB10391@plvision.eu \
    --to=vadym.kochan@plvision.eu \
    --cc=andrew@lunn.ch \
    --cc=andrii.savka@plvision.eu \
    --cc=andy.shevchenko@gmail.com \
    --cc=davem@davemloft.net \
    --cc=idosch@mellanox.com \
    --cc=jiri@mellanox.com \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mickeyr@marvell.com \
    --cc=netdev@vger.kernel.org \
    --cc=oleksandr.mazur@plvision.eu \
    --cc=serhiy.boiko@plvision.eu \
    --cc=serhiy.pshyk@plvision.eu \
    --cc=taras.chornyi@plvision.eu \
    --cc=volodymyr.mytnyk@plvision.eu \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).