From: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
To: MD Danish Anwar <danishanwar@ti.com>
Cc: aleksander.lobakin@intel.com, lukma@denx.de, m-malladi@ti.com,
diogo.ivo@siemens.com, rdunlap@infradead.org,
schnelle@linux.ibm.com, vladimir.oltean@nxp.com,
horms@kernel.org, rogerq@kernel.org, pabeni@redhat.com,
kuba@kernel.org, edumazet@google.com, davem@davemloft.net,
andrew+netdev@lunn.ch, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, netdev@vger.kernel.org, srk@ti.com,
Vignesh Raghavendra <vigneshr@ti.com>
Subject: Re: [PATCH net-next 3/4] net: ti: icssg-prueth: Add Multicast Filtering support for VLAN in MAC mode
Date: Thu, 19 Dec 2024 08:28:14 +0100 [thread overview]
Message-ID: <Z2PLDqqrLdXhLtAF@mev-dev.igk.intel.com> (raw)
In-Reply-To: <20241216100044.577489-4-danishanwar@ti.com>
On Mon, Dec 16, 2024 at 03:30:43PM +0530, MD Danish Anwar wrote:
> Add multicast filtering support for VLAN interfaces in dual EMAC mode
> for ICSSG driver.
>
> The driver uses vlan_for_each() API to get the list of available
> vlans. The driver then sync mc addr of vlan interface with a locally
> mainatined list emac->vlan_mcast_list[vid] using __hw_addr_sync_multiple()
> API.
>
> The driver then calls the sync / unsync callbacks and based on whether
> the ndev is vlan or not, driver passes appropriate vid to FDB helper
> functions.
>
> This commit also exports __hw_addr_sync_multiple() in order to use it
> from the ICSSG driver.
>
> Signed-off-by: MD Danish Anwar <danishanwar@ti.com>
> ---
> drivers/net/ethernet/ti/icssg/icssg_prueth.c | 69 ++++++++++++++++----
> drivers/net/ethernet/ti/icssg/icssg_prueth.h | 6 ++
> include/linux/netdevice.h | 3 +
> net/core/dev_addr_lists.c | 7 +-
> 4 files changed, 68 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
> index e031bccf31dc..a18773ef6eab 100644
> --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c
> +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
> @@ -472,30 +472,43 @@ const struct icss_iep_clockops prueth_iep_clockops = {
>
> static int icssg_prueth_add_mcast(struct net_device *ndev, const u8 *addr)
> {
> - struct prueth_emac *emac = netdev_priv(ndev);
> - int port_mask = BIT(emac->port_id);
> + struct net_device *real_dev;
> + struct prueth_emac *emac;
> + int port_mask;
> + u8 vlan_id;
>
> - port_mask |= icssg_fdb_lookup(emac, addr, 0);
> - icssg_fdb_add_del(emac, addr, 0, port_mask, true);
> - icssg_vtbl_modify(emac, 0, port_mask, port_mask, true);
> + vlan_id = is_vlan_dev(ndev) ? vlan_dev_vlan_id(ndev) : PRUETH_DFLT_VLAN_MAC;
> + real_dev = is_vlan_dev(ndev) ? vlan_dev_real_dev(ndev) : ndev;
Looks like a helper for that can be nice to have.
> + emac = netdev_priv(real_dev);
> +
> + port_mask = BIT(emac->port_id) | icssg_fdb_lookup(emac, addr, vlan_id);
> + icssg_fdb_add_del(emac, addr, vlan_id, port_mask, true);
> + icssg_vtbl_modify(emac, vlan_id, port_mask, port_mask, true);
>
> return 0;
> }
>
> static int icssg_prueth_del_mcast(struct net_device *ndev, const u8 *addr)
> {
> - struct prueth_emac *emac = netdev_priv(ndev);
> - int port_mask = BIT(emac->port_id);
> + struct net_device *real_dev;
> + struct prueth_emac *emac;
> int other_port_mask;
> + int port_mask;
> + u8 vlan_id;
> +
> + vlan_id = is_vlan_dev(ndev) ? vlan_dev_vlan_id(ndev) : PRUETH_DFLT_VLAN_MAC;
> + real_dev = is_vlan_dev(ndev) ? vlan_dev_real_dev(ndev) : ndev;
> + emac = netdev_priv(real_dev);
>
> - other_port_mask = port_mask ^ icssg_fdb_lookup(emac, addr, 0);
> + port_mask = BIT(emac->port_id);
> + other_port_mask = port_mask ^ icssg_fdb_lookup(emac, addr, vlan_id);
>
> - icssg_fdb_add_del(emac, addr, 0, port_mask, false);
> - icssg_vtbl_modify(emac, 0, port_mask, port_mask, false);
> + icssg_fdb_add_del(emac, addr, vlan_id, port_mask, false);
> + icssg_vtbl_modify(emac, vlan_id, port_mask, port_mask, false);
>
> if (other_port_mask) {
> - icssg_fdb_add_del(emac, addr, 0, other_port_mask, true);
> - icssg_vtbl_modify(emac, 0, other_port_mask, other_port_mask, true);
> + icssg_fdb_add_del(emac, addr, vlan_id, other_port_mask, true);
> + icssg_vtbl_modify(emac, vlan_id, other_port_mask, other_port_mask, true);
> }
>
> return 0;
> @@ -531,6 +544,28 @@ static int icssg_prueth_hsr_del_mcast(struct net_device *ndev, const u8 *addr)
> return 0;
> }
>
> +static int icssg_update_vlan_mcast(struct net_device *vdev, int vid,
> + void *args)
> +{
> + struct net_device *vport_ndev;
> + struct prueth_emac *emac;
> +
> + if (!vdev || !vid)
> + return 0;
> +
> + vport_ndev = vlan_dev_real_dev(vdev);
> + emac = netdev_priv(vport_ndev);
> +
> + netif_addr_lock_bh(vdev);
> + __hw_addr_sync_multiple(&emac->vlan_mcast_list[vid], &vdev->mc, vdev->addr_len);
Only question, why dev_mc_sync_multiple can't be used here?
> + netif_addr_unlock_bh(vdev);
> +
> + __hw_addr_sync_dev(&emac->vlan_mcast_list[vid], vdev,
> + icssg_prueth_add_mcast, icssg_prueth_del_mcast);
> +
> + return 0;
> +}
> +
> /**
> * emac_ndo_open - EMAC device open
> * @ndev: network adapter device
> @@ -772,12 +807,17 @@ static void emac_ndo_set_rx_mode_work(struct work_struct *work)
> return;
> }
>
> - if (emac->prueth->is_hsr_offload_mode)
> + if (emac->prueth->is_hsr_offload_mode) {
> __dev_mc_sync(ndev, icssg_prueth_hsr_add_mcast,
> icssg_prueth_hsr_del_mcast);
> - else
> + } else {
> __dev_mc_sync(ndev, icssg_prueth_add_mcast,
> icssg_prueth_del_mcast);
> + if (rtnl_trylock()) {
> + vlan_for_each(ndev, icssg_update_vlan_mcast, NULL);
> + rtnl_unlock();
> + }
> + }
> }
>
> /**
> @@ -828,6 +868,7 @@ static int emac_ndo_vlan_rx_add_vid(struct net_device *ndev,
> if (prueth->is_hsr_offload_mode)
> port_mask |= BIT(PRUETH_PORT_HOST);
>
> + __hw_addr_init(&emac->vlan_mcast_list[vid]);
> netdev_err(emac->ndev, "VID add vid:%u port_mask:%X untag_mask %X\n",
> vid, port_mask, untag_mask);
>
> diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
> index f5c1d473e9f9..4da8b87408b5 100644
> --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h
> +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
> @@ -83,6 +83,10 @@
> #define ICSS_CMD_ADD_FILTER 0x7
> #define ICSS_CMD_ADD_MAC 0x8
>
> +/* VLAN Filtering Related MACROs */
> +#define PRUETH_DFLT_VLAN_MAC 0
> +#define MAX_VLAN_ID 256
> +
> /* In switch mode there are 3 real ports i.e. 3 mac addrs.
> * however Linux sees only the host side port. The other 2 ports
> * are the switch ports.
> @@ -201,6 +205,8 @@ struct prueth_emac {
> /* RX IRQ Coalescing Related */
> struct hrtimer rx_hrtimer;
> unsigned long rx_pace_timeout_ns;
> +
> + struct netdev_hw_addr_list vlan_mcast_list[MAX_VLAN_ID];
> };
>
> /**
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index d917949bba03..a5c169b19543 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -4685,6 +4685,9 @@ int devm_register_netdev(struct device *dev, struct net_device *ndev);
> /* General hardware address lists handling functions */
> int __hw_addr_sync(struct netdev_hw_addr_list *to_list,
> struct netdev_hw_addr_list *from_list, int addr_len);
> +int __hw_addr_sync_multiple(struct netdev_hw_addr_list *to_list,
> + struct netdev_hw_addr_list *from_list,
> + int addr_len);
> void __hw_addr_unsync(struct netdev_hw_addr_list *to_list,
> struct netdev_hw_addr_list *from_list, int addr_len);
> int __hw_addr_sync_dev(struct netdev_hw_addr_list *list,
> diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c
> index 166e404f7c03..90716bd736f3 100644
> --- a/net/core/dev_addr_lists.c
> +++ b/net/core/dev_addr_lists.c
> @@ -242,9 +242,9 @@ static void __hw_addr_unsync_one(struct netdev_hw_addr_list *to_list,
> __hw_addr_del_entry(from_list, ha, false, false);
> }
>
> -static int __hw_addr_sync_multiple(struct netdev_hw_addr_list *to_list,
> - struct netdev_hw_addr_list *from_list,
> - int addr_len)
> +int __hw_addr_sync_multiple(struct netdev_hw_addr_list *to_list,
> + struct netdev_hw_addr_list *from_list,
> + int addr_len)
> {
> int err = 0;
> struct netdev_hw_addr *ha, *tmp;
> @@ -260,6 +260,7 @@ static int __hw_addr_sync_multiple(struct netdev_hw_addr_list *to_list,
> }
> return err;
> }
> +EXPORT_SYMBOL(__hw_addr_sync_multiple);
>
> /* This function only works where there is a strict 1-1 relationship
> * between source and destination of they synch. If you ever need to
> --
> 2.34.1
next prev parent reply other threads:[~2024-12-19 7:46 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-12-16 10:00 [PATCH net-next 0/4] Add Multicast Filtering support for VLAN interface MD Danish Anwar
2024-12-16 10:00 ` [PATCH net-next 1/4] net: ti: Kconfig: Select HSR for ICSSG Driver MD Danish Anwar
2024-12-18 16:59 ` Larysa Zaremba
2024-12-19 5:06 ` MD Danish Anwar
2024-12-19 16:59 ` Larysa Zaremba
2024-12-20 5:31 ` Anwar, Md Danish
2024-12-23 6:30 ` MD Danish Anwar
2024-12-20 19:30 ` kernel test robot
2024-12-16 10:00 ` [PATCH net-next 2/4] net: ti: icssg-prueth: Add VLAN support in EMAC mode MD Danish Anwar
2024-12-19 7:02 ` Michal Swiatkowski
2024-12-19 9:19 ` MD Danish Anwar
2024-12-16 10:00 ` [PATCH net-next 3/4] net: ti: icssg-prueth: Add Multicast Filtering support for VLAN in MAC mode MD Danish Anwar
2024-12-19 7:28 ` Michal Swiatkowski [this message]
2024-12-19 9:36 ` MD Danish Anwar
2024-12-19 9:57 ` Michal Swiatkowski
2024-12-16 10:00 ` [PATCH net-next 4/4] net: ti: icssg-prueth: Add Support for Multicast filtering with VLAN in HSR mode MD Danish Anwar
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=Z2PLDqqrLdXhLtAF@mev-dev.igk.intel.com \
--to=michal.swiatkowski@linux.intel.com \
--cc=aleksander.lobakin@intel.com \
--cc=andrew+netdev@lunn.ch \
--cc=danishanwar@ti.com \
--cc=davem@davemloft.net \
--cc=diogo.ivo@siemens.com \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lukma@denx.de \
--cc=m-malladi@ti.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=rdunlap@infradead.org \
--cc=rogerq@kernel.org \
--cc=schnelle@linux.ibm.com \
--cc=srk@ti.com \
--cc=vigneshr@ti.com \
--cc=vladimir.oltean@nxp.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.