public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
From: Paolo Abeni <pabeni@redhat.com>
To: michael.dege@renesas.com
Cc: paul@pbarker.dev, niklas.soderlund@ragnatech.se, kuba@kernel.org,
	yoshihiro.shimoda.uh@renesas.com, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org, edumazet@google.com,
	pabeni@redhat.com, linux-renesas-soc@vger.kernel.org,
	andrew+netdev@lunn.ch, davem@davemloft.net
Subject: Re: [net-next,v3,12/13] net: renesas: rswitch: add handler for FDB notification
Date: Thu,  2 Apr 2026 14:59:39 +0200	[thread overview]
Message-ID: <20260402125939.234488-1-pabeni@redhat.com> (raw)
In-Reply-To: <20260331-rswitch_add_vlans-v3-12-c37f41b1c556@renesas.com>

This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.

For local reproduction steps see https://netdev-ai.bots.linux.dev/ai-local.html
---
net: renesas: rswitch: add handler for FDB notification

The SWITCHDEV_FDB_ADD_TO_DEVICE notification writes the bridge MAC
address to the GWCA and adds a static rule to the MAC table. The
SWITCHDEV_FDB_DEL_TO_DEVICE removes the static rule from the MAC table.

> diff --git a/drivers/net/ethernet/renesas/rswitch.h b/drivers/net/ethernet/renesas/rswitch.h
> index 6dfc53c6b985..443fc4e49602 100644
> --- a/drivers/net/ethernet/renesas/rswitch.h
> +++ b/drivers/net/ethernet/renesas/rswitch.h

[ ... ]

> diff --git a/drivers/net/ethernet/renesas/rswitch_l2.c b/drivers/net/ethernet/renesas/rswitch_l2.c
> index f1c5c96027ba..ea95a87ed234 100644
> --- a/drivers/net/ethernet/renesas/rswitch_l2.c
> +++ b/drivers/net/ethernet/renesas/rswitch_l2.c

[ ... ]

> @@ -285,6 +269,181 @@ static int rswitch_switchdev_blocking_event(struct notifier_block *nb,
>  	return notifier_from_errno(ret);
>  }
>
> +static int rswitch_gwca_write_mac_address(struct rswitch_private *priv, const u8 *mac)
> +{
> +	int err;
> +
> +	err = rswitch_gwca_change_mode(priv, GWMC_OPC_CONFIG);
> +	if (err < 0)
> +		return err;
> +
> +	iowrite32((mac[0] << 8) | mac[1], priv->addr + GWMAC0);
> +	iowrite32((mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5],
> +		  priv->addr + GWMAC1);
> +
> +	return rswitch_gwca_change_mode(priv, GWMC_OPC_OPERATION);
> +}
> +
> +static int rswitch_add_addr_to_mactable(struct rswitch_private *priv, const u8 *mac)
> +{
> +	u32 index = priv->gwca.l2_shared_rx_queue->index;
> +	int err;
> +
> +	rswitch_modify(priv->addr, FWMACTL0, FWMACTL0_ED, 0);
> +	iowrite32((mac[0] << 8) | mac[1], priv->addr + FWMACTL1);
> +	iowrite32((mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5],
> +		  priv->addr + FWMACTL2);
> +	iowrite32(FWMACTL3_DSLV | FWMACTL3_SSLV,
> +		  priv->addr + FWMACTL3);
> +	iowrite32(FIELD_PREP(FWMACTL4_CSDL, index),
> +		  priv->addr + FWMACTL4(GWCA_INDEX));
> +	iowrite32(FIELD_PREP(FWMACTL5_DV, BIT(AGENT_INDEX_GWCA)),
> +		  priv->addr + FWMACTL5);
> +
> +	err = rswitch_reg_wait(priv->addr, FWMACTLR, FWMACTLR_L, 0);
> +	if (err < 0)
> +		return err;
> +
> +	if (ioread32(priv->addr + FWMACTLR))
> +		return NOTIFY_BAD;
> +
> +	return NOTIFY_DONE;
> +}
> +
> +static int rswitch_del_addr_from_mactable(struct rswitch_private *priv, const u8 *mac)
> +{
> +	int err;
> +
> +	rswitch_modify(priv->addr, FWMACTL0, 0, FWMACTL0_ED);
> +	iowrite32((mac[0] << 8) | mac[1], priv->addr + FWMACTL1);
> +	iowrite32((mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5],
> +		  priv->addr + FWMACTL2);
> +	iowrite32(FWMACTL3_DSLV | FWMACTL3_SSLV,
> +		  priv->addr + FWMACTL3);
> +	iowrite32(FIELD_PREP(FWMACTL4_CSDL, BIT(0)),
> +		  priv->addr + FWMACTL4(GWCA_INDEX));
> +	iowrite32(FIELD_PREP(FWMACTL5_DV, BIT(AGENT_INDEX_GWCA)),
> +		  priv->addr + FWMACTL5);
> +
> +	err = rswitch_reg_wait(priv->addr, FWMACTLR, FWMACTLR_L, 0);
> +	if (err < 0)
> +		return err;
> +
> +	err = ioread32(priv->addr + FWMACTLR);
> +	if (err)
> +		return NOTIFY_BAD;
> +
> +	return NOTIFY_DONE;
> +}
> +
> +static void rswitch_switchdev_bridge_fdb_event_work(struct work_struct *work)
> +{
> +	struct rswitch_switchdev_event_work *switchdev_work;
> +	struct rswitch_device *rdev;
> +	struct net_device *ndev;
> +
> +	switchdev_work = container_of(work, struct rswitch_switchdev_event_work, work);
> +	ndev = switchdev_work->ndev;
> +
> +	rtnl_lock();
> +
> +	/* Unfortunately all net_device members point to br0, there is no simple way to check
> +	 * if the event was triggered by a port device setting.
> +	 */
> +	rswitch_for_all_ports(switchdev_work->priv, rdev) {
> +		if (ether_addr_equal(rdev->ndev->dev_addr, switchdev_work->fdb_info.addr))
> +			goto out;
> +	}
> +
> +	/* Handle only bridge device */
> +	if (is_rdev(ndev))
> +		goto out;
> +
> +	switch (switchdev_work->event) {
> +	case SWITCHDEV_FDB_ADD_TO_DEVICE:
> +		rswitch_gwca_write_mac_address(switchdev_work->priv, switchdev_work->fdb_info.addr);
> +		rswitch_add_addr_to_mactable(switchdev_work->priv, switchdev_work->fdb_info.addr);
> +		break;
> +	case SWITCHDEV_FDB_DEL_TO_DEVICE:
> +		rswitch_del_addr_from_mactable(switchdev_work->priv, switchdev_work->fdb_info.addr);
> +		break;
> +	default:
> +		break;
> +	}
> +
> +out:
> +	rtnl_unlock();
> +
> +	kfree(switchdev_work->fdb_info.addr);
> +	kfree(switchdev_work);
> +	dev_put(ndev);
> +}
> +
> +/* called under rcu_read_lock() */
> +static int rswitch_switchdev_event(struct notifier_block *nb,
> +				   unsigned long event,
> +				   void *ptr)
> +{
> +	struct net_device *ndev = switchdev_notifier_info_to_dev(ptr);
> +	struct rswitch_switchdev_event_work *switchdev_work;
> +	struct switchdev_notifier_fdb_info *fdb_info;
> +	struct switchdev_notifier_info *info = ptr;
> +	struct rswitch_private *priv;
> +	int err;
> +
> +	priv = container_of(nb, struct rswitch_private, rswitch_switchdev_nb);
> +
> +	switch (event) {
> +	case SWITCHDEV_FDB_ADD_TO_DEVICE:
> +		fallthrough;
> +	case SWITCHDEV_FDB_DEL_TO_DEVICE:
> +		switchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC);
> +
> +		if (!switchdev_work)
> +			return NOTIFY_BAD;
> +
> +		switchdev_work->ndev = info->dev;
> +		switchdev_work->priv = priv;
> +		switchdev_work->event = event;
> +
> +		fdb_info = container_of(info,
> +					struct switchdev_notifier_fdb_info,
> +					info);
> +
> +		INIT_WORK(&switchdev_work->work, rswitch_switchdev_bridge_fdb_event_work);
> +
> +		memcpy(&switchdev_work->fdb_info, ptr, sizeof(switchdev_work->fdb_info));
> +
> +		switchdev_work->fdb_info.addr = kzalloc(ETH_ALEN, GFP_ATOMIC);
> +		if (!switchdev_work->fdb_info.addr)
> +			goto err_addr_alloc;
> +
> +		ether_addr_copy((u8 *)switchdev_work->fdb_info.addr,
> +				fdb_info->addr);
> +		dev_hold(ndev);
> +		queue_work(system_long_wq, &switchdev_work->work);
> +
> +		break;
> +	case SWITCHDEV_PORT_ATTR_SET:
> +		err = switchdev_handle_port_attr_set(ndev, ptr,
> +						     is_rdev,
> +						     rswitch_port_attr_set);
> +		return notifier_from_errno(err);
> +
> +		if (!is_rdev(ndev))
> +			return NOTIFY_DONE;
> +
> +		return notifier_from_errno(-EOPNOTSUPP);

Are these lines in the SWITCHDEV_PORT_ATTR_SET case reachable? The
return notifier_from_errno(err) above them looks like it returns
unconditionally.

Note: this dead code is removed in the next commit in the series
(ed3ab4a0a727 'net: renesas: rswitch: add vlan aware switching'),
which moves PORT_ATTR_SET handling to rswitch_switchdev_blocking_event
and removes this entire case from rswitch_switchdev_event.

> +	}
> +
> +	return NOTIFY_DONE;
> +
> +err_addr_alloc:
> +	kfree(switchdev_work);
> +
> +	return NOTIFY_BAD;
> +}
> +
>  int rswitch_register_notifiers(struct rswitch_private *priv)
>  {
>  	int err;


  reply	other threads:[~2026-04-02 12:59 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-31 10:03 [net-next PATCH v3 00/13] net: renesas: rswitch: R-Car S4 add VLAN aware switching Michael Dege
2026-03-31 10:03 ` [PATCH net-next v3 01/13] net: renesas: rswitch: improve port change mode functions Michael Dege
2026-04-02 12:59   ` [net-next,v3,01/13] " Paolo Abeni
2026-03-31 10:03 ` [PATCH net-next v3 02/13] net: renesas: rswitch: use device instead of net_device Michael Dege
2026-03-31 10:03 ` [PATCH net-next v3 03/13] net: renesas: rswitch: fix FWPC2 register access macros Michael Dege
2026-03-31 10:03 ` [PATCH net-next v3 04/13] net: renesas: rswitch: add register definitions for vlan support Michael Dege
2026-04-02 12:59   ` [net-next,v3,04/13] " Paolo Abeni
2026-04-02 13:02   ` [PATCH net-next v3 04/13] " Paolo Abeni
2026-03-31 10:03 ` [PATCH net-next v3 05/13] net: renesas: rswitch: add exception path for packets with unknown dst MAC Michael Dege
2026-04-02 12:59   ` [net-next,v3,05/13] " Paolo Abeni
2026-03-31 10:04 ` [PATCH net-next v3 06/13] net: renesas: rswitch: add forwarding rules for gwca Michael Dege
2026-04-02 12:59   ` [net-next,v3,06/13] " Paolo Abeni
2026-03-31 10:04 ` [PATCH net-next v3 07/13] net: renesas: rswitch: make helper functions available to whole driver Michael Dege
2026-03-31 10:04 ` [PATCH net-next v3 08/13] net: renesas: rswitch: add basic vlan init to rswitch_fwd_init Michael Dege
2026-03-31 10:04 ` [PATCH net-next v3 09/13] net: renesas: rswitch: update port HW init Michael Dege
2026-03-31 10:04 ` [PATCH net-next v3 10/13] net: renesas: rswitch: clean up is_rdev rswitch_device checking Michael Dege
2026-03-31 10:04 ` [PATCH net-next v3 11/13] net: renesas: rswitch: add passing of rswitch_private into notifiers Michael Dege
2026-03-31 10:04 ` [PATCH net-next v3 12/13] net: renesas: rswitch: add handler for FDB notification Michael Dege
2026-04-02 12:59   ` Paolo Abeni [this message]
2026-04-02 13:06   ` Paolo Abeni
2026-03-31 10:04 ` [PATCH net-next v3 13/13] net: renesas: rswitch: add vlan aware switching Michael Dege
2026-04-02 12:59   ` [net-next,v3,13/13] " Paolo Abeni

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=20260402125939.234488-1-pabeni@redhat.com \
    --to=pabeni@redhat.com \
    --cc=andrew+netdev@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-renesas-soc@vger.kernel.org \
    --cc=michael.dege@renesas.com \
    --cc=netdev@vger.kernel.org \
    --cc=niklas.soderlund@ragnatech.se \
    --cc=paul@pbarker.dev \
    --cc=yoshihiro.shimoda.uh@renesas.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox